使用名称空间来区分两个IUnitOfWork实现

本文关键字:两个 实现 IUnitOfWork 空间 | 更新日期: 2023-09-27 18:14:52

我正在开发一个ASP。.NET MVC 4 Web Api,使用c#, .NET Framework 4.0, Entity Framework Code First 6.0和Ninject。

我将需要两个不同的DbContext自定义实现,因为我需要连接两个不同的数据库。

这是我自定义的DbContext类实现之一。

public class EFDbContext : DbContext, IUnitOfWork
{
    public EFDbContext()
        : base("name=EFDbContext")
    {
        // If database doesn't exit, don't create it.
        Database.SetInitializer<EFDbContext>(null);
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new CONFIGURATIONSConfiguration());
        modelBuilder.Configurations.Add(new CODESConfiguration());
        modelBuilder.Configurations.Add(new AGGREGATION_CHILDSConfiguration());
        modelBuilder.Configurations.Add(new AGGREGATIONSConfiguration());
        base.OnModelCreating(modelBuilder);
    }
}

两个DbContext自定义类将继承IUnitOfWork和我的问题,如果我不知道如何区分它们在NinjectConfigurator类:

private void AddBindings(IKernel container)
{
    ConfigureLog4net(container);
    container.Bind<IUnitOfWork>().To<EFDbContext>().InRequestScope();
    // Hidden implementation...
}

如果我有两个不同的EFDbContext类,我如何在NinjectConfigurator上区分它们?

也许我可以使用相同的IUnitOfWork接口与两个不同的名称空间,并使用名称空间来区分它们。这里的问题是,我将在两个不同的名称空间中重复相同的界面。

使用名称空间来区分两个IUnitOfWork实现

你应该给它们命名。

Bind<IUnitOfWork>().To<EFDbContext>().Named("EF");
Bind<IUnitOfWork>().To<OtherDbContext>().Named("Other"); 

允许你这样做:

class MyRepository {
    private IUnitOfWork _unitOfWork;
    public([Named("EF")] IUnitOfWork unitOfWork)
        _unitOfWork = unitOfWork;
    }
}

您还可以为这两个上下文创建接口。例如IEFDbContext1IEFDbContext2。那么你的代码可以是:

Bind<IEFDbContext1>().To<EFDbContext1>().InRequestScope();
Bind<IEFDbContext2>().To<EFDbContext2>().InRequestScope();

给它一个更有意义的名字也是一个好主意,因为目前EFDbContext并没有告诉他太多的责任。

我认为使用单独的接口也可以帮助你在单元测试,如果你需要模拟上下文。