C# 使用工作单元和存储库模式与MVC的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

我目前正在使用依赖注入(autofac)建立一个新的mvcweb应用程序。我真的很了解依赖注入,所以我觉得我错过了一些东西。我有一个可行的解决方案(发布在下面),但我觉得我的解决方案与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();
基本上,我有一个服务,该服务有多个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();