如何重构类似的控制器?



在我的项目中,有两个(到目前为止,将来可能会有更多)非常相似的控制器。

DevelopersController

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace H4P.Controllers
{
public class DevelopersController : Controller
{
private DataManager dataManager;
public int PageSize = 10;
public DevelopersController(DataManager repo)
{
dataManager = repo;
}
public async Task<IActionResult> Index(int pageNumber = 1)
{
var developers = dataManager.DevelopersRepository.Developers.AsNoTracking();
return View(await PaginatedList<Developer>.CreateAsync(developers, pageNumber, PageSize));
}
public IActionResult Developer(string id)
{
return View(dataManager.DevelopersRepository.GetDeveloperById(Guid.Parse(id)));
}
}
}

和TagsController

using H4P.Domain;
using H4P.Models;
using H4P.Models.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace H4P.Controllers
{
public class TagsController : Controller
{
private DataManager dataManager;
public int PageSize = 10;
public TagsController(DataManager repo)
{
dataManager = repo;
}
public async Task<IActionResult> Index(int pageNumber = 1)
{
var tags = dataManager.TagsRepository.Tags.AsNoTracking();
return View(await PaginatedList<Tag>.CreateAsync(tags, pageNumber, PageSize));
}
public IActionResult Tag(string id)
{
return View(dataManager.TagsRepository.GetTagById(Guid.Parse(id)));
}
}
}

同时,标签类和开发者类有相同的父类FilterBase。

public abstract class FilterBase
{
[Required]
public Guid Id { get; set; }
public virtual string Title { get; set; }
public virtual string Text { get; set; }
public virtual List<Game> Games { get; set; } = new List<Game>();
}
public class Tag : FilterBase
{
//
}
public class Developer : FilterBase
{
//
}

因此,起初我只是想将这些控制器组合成一个FiltersController,其中代码与FilterBase模型一起工作。但是我需要标签和开发者有不同的路由。

  • .../tags-用于Index方法(输出页面上的所有标签)
  • .../tag/id-用于Tag方法(显示特定标签的信息)

和类似的开发者

  • .../developers
  • ../developer/id

我的另一个选择是使用共享视图。这些TagsControllerDeveloperController将传递给这个视图FilterBase对象。然而,这只能解决视图的问题,但对于类似的控制器,它仍然是一个问题。

最后,这是我的问题:这需要重构吗?如果有,是怎么做到的?

我很乐意听取任何建议。如果你需要更多的信息,写信给我,我会提供给你。

泛化并不总是好的。正如您所看到的,您有两个不同的上下文,开发人员和标签,仅仅因为它们使用CRUD操作而以相同的方式看待它们并不是一个好主意。并且会给系统的进一步开发带来问题。有时为了更好地分离概念,最好使用重复的代码。

,但它可以在另一个级别解决,例如使用存储库和CRUD存储库实现,接受TEntity作为通用参数。

当您使用efcore时,请查看DbContext.Set()函数。

一个选项可能是为DeveloperTag控制器创建一个基本控制器:

public class FilterController
{
public FilterBase Filter { get; set; }
}

并在每个控制器中创建一个自定义过滤器实例:

public class DevelopersController : FilterController
{
public DevelopersController(DataManager repo)
{
dataManager = repo;

this.Filter = new Developer();
}
}
public class TagsController : FilterController
{
public TagsController(DataManager repo)
{
dataManager = repo;
this.Filter = new Tag();
}
}

这样你就有了你的路由,视图…没有改变和你的过滤器。如果需要(如果派生的Filter类有许多自定义方法),可以添加Filter类的派生属性,以便轻松地使用派生类。例如,在您的DeveloperController:

public Developer DeveloperFilter => (Developer)this.Filter;

同样,如果你使用依赖注入,你可以注入FilterBase属性,而不是在构造函数中创建。

相关内容

  • 没有找到相关文章

最新更新