Reputation: 121
Here is my method :
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();
}
}
In here i used "using" keyword to get dbContext. In every methods I did this because we have different connection string. I hope this is not a bad way to write methods in entity framwork. I realized this when I was going to write unit test for each methods in the business layer. I want to write a constructor to get dbcontext in generic way. I can use Dependency Injection to do that but i don't know how to do that. Can someone give me a way to do it?
Upvotes: 1
Views: 859
Reputation: 1720
If you just need to hide the logic of building connections string, you can use Factory pattern as it is. In this example building of connection string depends of clientId and is encapsulted in factory. You can mock it as you like in your unit tests for 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;
}
}
Upvotes: 0
Reputation: 2627
Create and Interface IDbFactory
public interface IDbFactory
{
DbContext GetConnection();
}
Create a class DbFactory
public class DbFactory : IDbFactory
{
public DbContext GetConnection()
{
var connectionString = [get this from web.config]
return new DbContext.Create(connectionString);
}
}
Inject dependacny for IDbFactory in the constructor then
public async task<model> GetMemberList(CancellationToken cancelToken)
{
try
{
await Task.Run(() =>
{
using (var db = _dbFactory.GetConnection())
{
// Code Goes Here....
}
}, cancelToken);
}
catch
{
Throw New Exception();
}
}
Hope it helps
Upvotes: 1