C# 使用工作单元和存储库模式与MVC的Autofac关系问题
我目前正在使用依赖注入(autofac)建立一个新的mvcweb应用程序。我真的很了解依赖注入,所以我觉得我错过了一些东西。我有一个可行的解决方案(发布在下面),但我觉得我的解决方案与Autofac试图做的相反,它解决了依赖关系C# 使用工作单元和存储库模式与MVC的Autofac关系问题,c#,model-view-controller,autofac,C#,Model View Controller,Autofac,我目前正在使用依赖注入(autofac)建立一个新的mvcweb应用程序。我真的很了解依赖注入,所以我觉得我错过了一些东西。我有一个可行的解决方案(发布在下面),但我觉得我的解决方案与Autofac试图做的相反,它解决了依赖关系 builder.Register(c => { IDatabaseFactory factory = c.Resolve<IDatabaseFactory>(); GenericRepository<ContactSubscrip
builder.Register(c =>
{
IDatabaseFactory factory = c.Resolve<IDatabaseFactory>();
GenericRepository<ContactSubscription> repo = c.Resolve<GenericRepository<ContactSubscription>>(
new NamedParameter("factory", (object)factory));
return new TestUnitOfWork(factory, repo);
}).AsSelf().InstancePerLifetimeScope();
基本上,我有一个服务,该服务有多个UnitOfWork,每个UnitOfWork有多个存储库,它们共享一个dbcontext实例(由UnitOfWork拥有)。我需要为UnitOfWork构建的IDatabaseFactory传递到存储库中。这是为了防止存储库在singleUnitOfWork实例中处理另一个存储库正在使用的上下文
这就是我尝试过的
服务的简化模型
一个简单实现的工作单元(基于msdn示例的接口)我遗漏了接口,它只是做了一些与问题无关的事情(我们无法通过构建)。ContactSubscription只是一个模型
public class TestUnitOfWork : UowBase, IUnitOfWork
{
public TestUnitOfWork(IDatabaseFactory factory,
GenericRepository<ContactSubscription> repo)
: base(factory)
{
}
}
注册情况如下:
builder.RegisterType()
.As()
.InstancePerRequest();
建造商登记通用(类型(通用存储))
.AsSelf()
.As(类型(假定))
.InstancePerLifetimeScope();
builder.RegisterType().AsSelf().InstancePerRequest();
builder.RegisterType().AsSelf().InstancePerRequest();
builder.RegisterType();
我目前的成绩
当使用UnitOfWork作为InstancePerRequest时,我们得到了很好但不是很好的结果。IDatabaseContext在所属服务的UnitOfWork的所有实例之间共享。使用autofac的其他注册方法似乎会为每次使用创建IDatabaseFactory的新实例,例如在注册时使用InstancesPerLifetimeScope
工作(但感觉不对)解决方案
或者,这种方法是有效的,但是对于依赖项注入来说是新的,通过解析依赖项,我觉得我违背了Autofac的意图
builder.Register(c =>
{
IDatabaseFactory factory = c.Resolve<IDatabaseFactory>();
GenericRepository<ContactSubscription> repo = c.Resolve<GenericRepository<ContactSubscription>>(
new NamedParameter("factory", (object)factory));
return new TestUnitOfWork(factory, repo);
}).AsSelf().InstancePerLifetimeScope();
builder.Register(c=>
{
IDatabaseFactory工厂=c.Resolve();
一般保存回购=c.解决(
新名称参数(“工厂”,“对象工厂”);
返回新的TestUnitOfWork(工厂、回购);
}).AsSelf().InstancePerLifetimeScope();
我强烈感觉上面的解决方案并不理想(我对loc容器知之甚少),我想看看是否有一种更有效的方法让Autofac正在构建的IDatabaseFactory让UnitOfWork将相同的实例传递到存储库,而不是让我自己更头疼,但对于其他UnitOfWork,不能保留相同的实例
我的项目现在一团糟,所以希望示例代码没有我遗漏的任何打字错误或旧变量。谢谢大家! 稍作休息后,我找到了解决问题的办法。由于UnitOfWork已经在抽象数据库上下文,并且UnitOfWork是一个注入的依赖项,因此每个UnitOfWork现在控制每个存储库的创建和生存期。没有必要注入存储库 以下是我的解决方案:
public interface INewsletterUnitOfWork
{
IRepository<Newsletter> NewsLetters { get; }
IRepository<ContactSubscription> ContactSubscriptions { get; }
}
public class NewsletterUnitOfWork : UowBase, INewsletterUnitOfWork
{
private IRepository<Newsletter> _newsletters;
public IRepository<Newsletter> NewsLetters
{
get { return _newsletters ?? (_newsletters = new GenericRepository<Newsletter>(Context)); }
private set { _newsletters = value; }
}
private IRepository<ContactSubscription> _contactSubscriptions;
public IRepository<ContactSubscription> ContactSubscriptions
{
get { return _contactSubscriptions ?? (_contactSubscriptions = new GenericRepository<ContactSubscription>(Context)); }
private set { _contactSubscriptions = value; }
}
public NewsletterUnitOfWork(IDatabaseFactory factory)
: base(factory)
{ }
}
WSLetterUnitOfWork中的公共接口
{
IRepository时事通讯{get;}
i假定联系人订阅{get;}
}
公共类新闻稿UnitOfWork:UowBase,INewsletterUnitOfWork
{
私人电子杂志;
公共电子信息通讯
{
获取{返回}时事通讯???({时事通讯=新的通用存储库(上下文));}
私有集{u时事通讯=value;}
}
私人电子邮箱订阅;
公共IRepository联系人订阅
{
获取{return _contactSubscriptions???(_contactSubscriptions=new generirepository(Context));}
私有集{u contactSubscriptions=value;}
}
公共通讯工作单位(IDatabaseFactory)
:基地(工厂)
{ }
}
注册很好,简单,干净
builder.RegisterType<DefaultDatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
builder.RegisterType<NewsletterUnitOfWork>()
.AsSelf()
.As<INewsletterUnitOfWork>()
.InstancePerLifetimeScope();
builder.RegisterType();
builder.RegisterType()
.AsSelf()
.As()
.InstancePerLifetimeScope();
builder.Register(c =>
{
IDatabaseFactory factory = c.Resolve<IDatabaseFactory>();
GenericRepository<ContactSubscription> repo = c.Resolve<GenericRepository<ContactSubscription>>(
new NamedParameter("factory", (object)factory));
return new TestUnitOfWork(factory, repo);
}).AsSelf().InstancePerLifetimeScope();
public interface INewsletterUnitOfWork
{
IRepository<Newsletter> NewsLetters { get; }
IRepository<ContactSubscription> ContactSubscriptions { get; }
}
public class NewsletterUnitOfWork : UowBase, INewsletterUnitOfWork
{
private IRepository<Newsletter> _newsletters;
public IRepository<Newsletter> NewsLetters
{
get { return _newsletters ?? (_newsletters = new GenericRepository<Newsletter>(Context)); }
private set { _newsletters = value; }
}
private IRepository<ContactSubscription> _contactSubscriptions;
public IRepository<ContactSubscription> ContactSubscriptions
{
get { return _contactSubscriptions ?? (_contactSubscriptions = new GenericRepository<ContactSubscription>(Context)); }
private set { _contactSubscriptions = value; }
}
public NewsletterUnitOfWork(IDatabaseFactory factory)
: base(factory)
{ }
}
builder.RegisterType<DefaultDatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
builder.RegisterType<NewsletterUnitOfWork>()
.AsSelf()
.As<INewsletterUnitOfWork>()
.InstancePerLifetimeScope();