Asp.net mvc microsoftmvc中服务层和存储库的设计

Asp.net mvc microsoftmvc中服务层和存储库的设计,asp.net-mvc,linq,design-patterns,repository,Asp.net Mvc,Linq,Design Patterns,Repository,我对微软MVC有以下问题——或者说,迫切需要有价值的建议。客户的某项行动导致创建: 桌上的一句话 表中用于小时登记的条目 变更日志中的票证条目 我为业务操作使用服务层,为CRUD操作使用存储库。问题是我有时需要连接来自不同DataContext的对象,所以我认为我使用的是有缺陷的设计。最近,我们开始从控制器和存储库中删除所有业务逻辑,这是我遇到的第一件事 例如: BLogic.AddRemarks(Ticket t, ...) { Remark r = _remarksRepositor

我对微软MVC有以下问题——或者说,迫切需要有价值的建议。客户的某项行动导致创建:

  • 桌上的一句话
  • 表中用于小时登记的条目
  • 变更日志中的票证条目
我为业务操作使用服务层,为CRUD操作使用存储库。问题是我有时需要连接来自不同DataContext的对象,所以我认为我使用的是有缺陷的设计。最近,我们开始从控制器和存储库中删除所有业务逻辑,这是我遇到的第一件事

例如:

BLogic.AddRemarks(Ticket t, ...)
{
  Remark r = _remarksRepository.Create();
  r.Ticket = t;
  _remarksRepository.Add(r);
  _remarksRepository.Save();
}
这会触发kBOOM,因为票据是使用存储库在控制器中获取的。因此备注r和票证t不共享相同的数据上下文

我可以修改方法的签名并提供一个int TicketId,但这感觉不对。此外,接下来我会遇到类似的问题


我的存储库是在服务类的构造函数中创建的。也许我必须在方法开始时创建它们?即使这样,我也必须经常传输ID而不是真正的对象。

我的建议是使用依赖注入(或控制反转-取决于您希望如何调用它)。我用自己的城堡温德尔。与mvc.net集成非常简单

当IoC启动并运行时,创建ContextManager。像这样的事情:

public class ContextManager : IContextManager
{
    private XContext context;

    public XContext GetContext()
    {
        return context ?? (context = XContext.Create());
    }
}
public class MyController : Controller
{
    public ISomeService SomeService { get; set; }
    public IContextManager ContextManager { get; set; }

...

}
将IContextManager生活方式设置为perwebrequest,您就获得了可以从存储库和服务访问的上下文。每个请求都是一样的

编辑

您还必须创建自己的controllerFactory

然后,您可以像这样使用您的服务和存储库:

public class ContextManager : IContextManager
{
    private XContext context;

    public XContext GetContext()
    {
        return context ?? (context = XContext.Create());
    }
}
public class MyController : Controller
{
    public ISomeService SomeService { get; set; }
    public IContextManager ContextManager { get; set; }

...

}

您不必为服务和存储库创建新实例,您可以通过配置管理这些对象。最合理的是独生子女

术语DI和IoC是不可互换的,意思是两个不同的东西。您可以通过使用DI实现IoC。Windsor、Unity和Ninject是用于反转控制的DI框架所以在控制器操作开始时,我应该初始化一个上下文管理器并从中取出必要的对象?我是否可以从服务层访问上下文管理器而不在那里显式提供它?或者这是服务层内的解决方案,因为我可以使用所需的datacontext创建存储库。@Paul使用控制器的构造函数包含ContextManager依赖项。对服务层类执行相同的操作。不要在方法中实例化ContextManager。谢谢您的回答!目前我认为最合理的解决方案确实是在控制器中创建datacontext。从那里我可以初始化服务层。服务层可以初始化存储库。因此,整个“链”将共享相同的数据上下文。