洋葱架构:尊重应用程序的MVC层中的依赖关系

时间:2017-06-20 09:49:42

标签: asp.net-mvc onion-architecture

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

  1. 域:实体/域接口
  2. 存储库:使用实体框架代码第一种方法的通用存储库(现在)
  3. 服务:调用存储库的通用服务
  4. MVC
  5. 现在我正在尝试在我的控制器中创建一个方法来开始测试我在RepositoryService中实现的方法,我很难知道我可以创建什么在这个控制器中。我想在Get中测试一个简单的Repository方法,但为了做到这一点,我需要在控制器中使用GenericService个对象和GenericRepository对象。为了演示我的意思,这里是我的GenericRepository的片段(我将跳过界面):

    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>();
        }
    }
    

    现在我的GenericService:

    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中的方法,但我确实需要添加对项目的引用。

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

    编辑我认为我的问题的答案在于Startup.cs我可以在service.addScoped(typeof(IGenericRepository<>),typeof(GenericRepository<>));这样的内容 但是我不确定这个,有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果有人遇到同样的问题,我会自己回答这个问题。我们可以使用配置方法在需要时创建类的实例。在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需要知道Repositories以及Services。  可以在这里找到一个非常好的答案:Onion Architecture : Can UI depend on Domain