这应该很容易解释,但我不确定如何将解决方案应用到我的DI容器(Autofac)中。
我有一个存储库
public class ClientRepository
{
public ClientRepository(MyContext context)
{
}
}
然后是工作单位
public class UnitOfWork
{
public UnitOfWork(MyContext context, ClientRepository repository)
{
}
}
工作单元/存储库模式规定将工作单元实例化的DataContext应传递到存储库的构造函数中,这样一切都使用相同的DataContext
换句话说,AutoFac应该基本上应该这样做......
MyContext context = new MyContext();
ClientRepository clientRepository = new ClientRepository(context);
UnitOfWork unitOfWork = new UnitOfWork(context, clientRepository);
如何告诉Autofac正确连接?
回应Cyril关于使用Func> ...
的评论我有一个“ClientService”类需要这些UnitOfWorks中的一个或多个。在下面的示例中,“添加”和“删除”的工作单元之间不应存在依赖关系共享(除非我已将依赖关系注册为Singleton)。如果我不使用Func&gt ;,例如单独的范围,我怎么能实现这种分离?
public class ClientService
{
private readonly Func<Owned<UnitOfWork>> _unitOfWorkFactory;
public ClientService(Func<Owned<UnitOfWork>> unitOfWorkFactory)
{
_unitOfWorkFactory = unitOfWorkFactory;
}
public AddClients(Clients c)
{
using(var uoc = _unitOfWorkFactory())
{
}
}
public DeleteClients(Clients C)
{
using(var uoc = _unitOfWorkFactory())
{
}
}
}
答案 0 :(得分:-1)
使Autofac基本上能满足您的需求:
所以
public static class DependencyContainer
{
internal static IContainer Container;
public static IContainer CreateContainer(Assembly assembly)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(assembly);
IModule[] modules =
{
//You don't have to create lots of modules...
//but it would be better to have different modules for different application layers
new DataModule( /*some params if you need*/),
new DataAccessModule( ),
//new BusinessLogicModule(),
//...
};
foreach (var module in modules)
{
builder.RegisterModule(module);
}
return Container;
}
}
2-3。实现容器和寄存器类型中使用的模块
DataModule的:
internal class DataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//When you specify InstancePerRequest it means that everything (resolved via this DI)
//is using the same DataContext for current request
builder.RegisterType<MyContext>().As<MyContext>().InstancePerRequest();
}
}
DataAccessModule:
internal class DataAccessModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<UnitOfWork>().As<UnitOfWork>().InstancePerRequest();
builder.RegisterType<ClientRepository>().As<ClientRepository>().InstancePerRequest();
//if you are using generic repository you can register all them in one line like this:
//builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerRequest();
}
}
在Global.asax.cs中设置DependencyResolver
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
//Default Application_Start() content
//...
//Using our DI
var container = DependencyContainer.CreateContainer(typeof(MvcApplication).Assembly);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
用法示例
public class MyController : Controller
{
private readonly UnitOfWork _unitOfWork;
private readonly ClientRepository _clientRepository;
public MyController(UnitOfWork unitOfWork, ClientRepository clientRepository)
{
_unitOfWork = unitOfWork;
_clientRepository = clientRepository;
}
//When you are calling action DoSomething, you don't have to worry about constructor params (DI will pass them)
public ActionResult DoSomething()
{
_clientRepository.DoSomething();
return PartialView("DoSomething");
}
}