当连接字符串不同时,如何使用构造函数实现DbContext?

时间:2018-08-29 07:55:42

标签: c# entity-framework dependency-injection

这是我的方法:

public async task<model> GetMemberList(CancellationToken cancelToken, string connString)
{
   try
   {
       await Task.Run(() =>
       {
           using (var dbContext = DbContext.Create(connString))
           {
              // Code Goes Here....
           }
       }, cancelToken);
   }
   catch
   {
      Throw New Exception(); 
   }
}

在这里,我使用“ using”关键字来获取dbContext。在每种方法中,我这样做都是因为我们有不同的连接字符串。我希望这不是在实体框架中编写方法的不错方法。当我要为业务层中的每种方法编写单元测试时,我意识到了这一点。我想编写一个构造函数以通用方式获取dbcontext。我可以使用依赖注入来做到这一点,但我不知道该怎么做。有人可以给我一种方法吗?

2 个答案:

答案 0 :(得分:1)

创建和接口IDbFactory

public interface IDbFactory
{
    DbContext GetConnection();
}

创建一个类DbFactory

public class DbFactory : IDbFactory
{ 
    public DbContext GetConnection()
    {
        var connectionString = [get this from web.config]
        return new DbContext.Create(connectionString);
    }
}

然后在构造函数中为IDbFactory注入dependacny

public async task<model> GetMemberList(CancellationToken cancelToken)
{
   try
   {
       await Task.Run(() =>
       {
           using (var db = _dbFactory.GetConnection())
           {
              // Code Goes Here....
           }
       }, cancelToken);
   }
   catch
   {
      Throw New Exception(); 
   }
}

希望有帮助

答案 1 :(得分:0)

如果您只需要隐藏建筑连接字符串的逻辑,则可以按原样使用Factory模式。在此示例中,连接字符串的构建取决于clientId,并封装在工厂中。您可以在SomeService的单元测试中随意模拟它。

public class CompositionRoot
{
    private readonly IContainer _root;

    public CompositionRoot()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<SomeService>();
        builder.RegisterType<DbContextFactory>().As<IDbContextFactory>();

        _root = builder.Build();
    }

    public T GetService<T>()
    {
        return _root.Resolve<T>();
    }
}

public interface IDbContextFactory
{
    DbContext Get(int clientId);
}

public class DbContextFactory : IDbContextFactory
{
    public DbContext Get(int clientId)
    {
        // place here any logic you like to build connection string
        var connection = $"Data Source={clientId}db";
        return new DbContext(new SqlConnection(connection), true);
    }
}

public class SomeService
{
    private readonly IDbContextFactory _dbFactory;

    public SomeService(IDbContextFactory dbFactory)
    {
        _dbFactory = dbFactory ?? throw new ArgumentNullException(nameof(dbFactory));
    }

    public async Task<Model> GetMemberList(CancellationToken cancelToken, int clientId)
    {
        using (var dbContext = _dbFactory.Get(clientId))
        {
            // Code Goes Here....

        }

        return null;
    }
}