【问题标题】:Onion architecture : respecting dependencies in the MVC Layer of the application洋葱架构:尊重应用程序 MVC 层中的依赖关系
【发布时间】:2017-06-20 09:49:41
【问题描述】:

我正在使用 ASP.NET MVC 和洋葱架构制作网站。我有以下架构:

  1. 域:实体/域接口
  2. 存储库:使用实体框架代码优先方法的通用存储库(目前)
  3. 服务:调用存储库的通用服务
  4. MVC

现在我试图在我的控制器中创建一个方法来开始测试我在RepositoryService 中实现的方法,但我很难知道我可以在这个控制器中创建什么。我想在Repository 中测试一个简单的Get 方法,但要做到这一点,我需要在我的控制器中使用GenericService 对象和GenericRepository 对象。为了演示我的意思,这里是我的 GenericRepository 的 sn-p(我将跳过接口):

public class GenericRepository<T> : IGenericRepository<T> where T : class
{
    private readonly PrincipalServerContext context;
    private DbSet<T> entities;
    public Repository(PrincipalServerContext context)
    {
        this.context = context;
        entities = context.Set<T>();
    }
}

现在我的通用服务:

public class GenericService<T> : IGenericService<T> where T : class
{
    private IRepository<T> repository;

    public GenericService(IRepository<T> repository)
    {
        this.repository = repository;
    }
    public T GetEntity(long id)
    {
        return repository.Get(id);
    }
}

最后,我的问题是,我是否允许在我的控制器中创建这些对象,如下所示(使用我的名为 PrincipalServerContext 的 dbcontext):

public class NavigationController : Controller
{
    private IGenericService<DomainModelClassHere> domainService;
    private IGenericRepository<DomainModelClassHere> domainRepo;
    private PrincipalServerContext context;

    public ActionResult MyMethod(){
        context = new PrincipalServerContext();
        domainRepo = new GenericRepository<DomainModelClassHere>(context);
        domainService = new GenericService<DomainModelClassHere>(domainRepo);
        if(domainService.GetEntity(1)==null)
           return View("UserNotFound");//Just as an example
        return View();
    }
}

这是允许的吗?根据 Jeffrey Palermo 的说法,UI 可以依赖于 ServiceDomain,所以我不知道 Repository。从技术上讲,我没有使用来自 repository 的方法,但我确实需要添加对项目的引用。

如果我不能,那么如果我没有GenericRepository,我该如何创建一个新的GenericService?有没有更好的方法来实例化我的对象?

编辑我认为我的问题的答案存在于Startup.cs 中,我可以在其中输入service.addScoped(typeof(IGenericRepository&lt;&gt;),typeof(GenericRepository&lt;&gt;)); 之类的内容 但我不确定这一点,有什么想法吗?

【问题讨论】:

    标签: asp.net-mvc onion-architecture


    【解决方案1】:

    如果有人遇到同样的问题,我会自己回答。我们可以在需要时使用一些配置方法来创建类的实例。在Startup.cs 文件中,您必须添加ConfigureServices(IServiceCollection services) 方法,其中有几种方法可以应用于services 以创建这些实例。例如,您可以使用:

    services.AddTransient(IGenericRepository, GenericRepository)
    

    What is the difference between services.AddTransient, service.AddScope and service.AddSingleton methods in Asp.Net Core 1?(此链接解释了方法之间的差异)。

    AddTransient 在我的情况下很好,因为它在应用程序的整个生命周期中创建了一个对象的实例,这正是我所需要的。这意味着 UI 依赖于解决方案的其余部分,因为 Startup.cs 需要了解 RepositoriesServices。 在这里可以找到一个很好的答案:Onion Architecture : Can UI depend on Domain

    【讨论】:

    • re: AddTransient is good in my case because it creates an instance of an object through the whole lifespan of the application, which is what I need. 实际上,如果您希望在应用程序的整个生命周期中拥有一个实例,所有控制器+请求都将共享该实例,那么您需要的是 AddSingleton也就是说,在你的情况下,我认为你不想要这个(每个请求共享一个 Repo/DBContext)。所以你应该用IServiceCollection.AddDBContextdocs.microsoft.com/en-us/aspnet/core/data/ef-mvc/…注册PrincipleServerContext
    猜你喜欢
    • 2013-01-31
    • 1970-01-01
    • 2015-03-17
    • 2015-05-19
    • 2020-03-23
    • 2011-01-21
    • 2017-11-23
    • 2011-12-08
    • 1970-01-01
    相关资源
    最近更新 更多