使用Ninject在我的存储库类中设置DBContext的连接字符串

时间:2014-12-27 17:46:40

标签: c# asp.net-mvc-5 repository ninject

我有一个使用EF 6的MVC 5应用程序,并使用DI容器Ninject实现具有依赖注入的Repository模式。 dbcontext的连接字符串存储在EF Context正确找到的Web.config文件中。一切正常。最近,我要求需要在运行时确定与我的DBContext的连接并连接到不同的数据库(但具有完全相同的结构)。因此,我需要在实例化存储库之前在运行时从实体连接字符串更改sql connectionstring部分。我真的很感激帮助。我不是DI大师;知道足够的Ninject让我的事情继续下去。

这是我的存储库基础接口:

public interface IRepositoryBase<T> where T : class
{
    void Add(T entity, string userGuid = "");
    void Delete(T entity);
    // ... removed other method signatures for brevity
}

我的存储库基础实现:

public abstract class RepositoryBase<D, T> : IRepositoryBase<T>, IDisposable
where T : class
where D : DbContext, new()
{
    private Guid? currUserGuid = null;
    private D dataContext;
    protected D DataContext
    {
        get
        {
            if (dataContext == null)
                dataContext = new D();
            return dataContext;
        }
        set { dataContext = value; }
    }

    public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate)
    {
        return DataContext.Set<T>().Where(predicate);
    }
    public virtual IQueryable<T> GetAll()
    {
        IQueryable<T> query = DataContext.Set<T>();
        return query;
    }

    public virtual void Delete(T entity)
    {
        OperationStatus stat = TryDelete(entity);
    }
    // .... removed rest for brevity
}

具体类的接口和实现:

    public interface ICustomerRepository : IRepositoryBase<Customer>
{
    Customer GetCustomerAndStatus( Guid custGuid );
}
public class CustomerRepository : RepositoryBase<PCDataEFContext, Customer>, ICustomerRepository
{
    public Customer GetCustomerAndStatus( Guid custGuid )
    {
        return DataContext.Customers.Include( x => x.CustStatusType )
        .SingleOrDefault( x => x.PKGuid == custGuid );
    }
}

我的Ninject依赖解析器:

    public class NinjectDependencyResolver : IDependencyResolver
{
    private IKernel kernel;

    public NinjectDependencyResolver()
    {
        kernel = new StandardKernel();
        AddBindings();
    }
    public IKernel Kernel { get { return kernel; } }

    private void AddBindings()
    {
        kernel.Bind<ICustomerRepository>().To<CustomerRepository>();
        // ... other bindings are omitted for brevity
    }
}

最后,这是我的Entity Framework生成的DBContext:

public partial class PCDataEFContext : DbContext
{
    public PCDataEFContext()
        : base("name=PCDataEFContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Customer> Customers { get; set; }
}

以上所有代码都很棒!但正如我在开始时所说的,我不知道如何在运行时将连接字符串注入我的Repositorybase类中,这样我就不必修改任何继承的存储库(我有很多这些存储库) 。有人请帮忙。

巴布。

1 个答案:

答案 0 :(得分:0)

你能这样做吗?

public partial class PCDataEFContext : DbContext
{
    public PCDataEFContext()
        : base(Util.GetTheConnectionString())
    { }
}

public class MyDerivedContext : PCDataEFContext
{
    public MyDerivedContext()
        : base()
    { }
}

class Util
{
    public static string GetTheConnectionString()
    {
        // return the correct name based on some logic...
        return "name=PCDataEFContext";
    }
}

另一种方法,可以在你定义的RepositorBase类中,通过在创建dbcontext之后更改connectionstring:

    protected D DataContext
    {
        get
        {
            if (dataContext == null)
            {
                dataContext = new D();
                dataContext.Database.Connection.ConnectionString = "the new connectionstring";
            }
            return dataContext;
        }
        set { dataContext = value; }
    }