1

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?

8
  • Are you using .Net core? Commented Aug 29, 2018 at 8:01
  • No @AkbarBadhusha. Commented Aug 29, 2018 at 8:07
  • 1
    What rules do you use to choose connection string? It is possible to configure dependency injection container to inject DbContext with different parameters to different classes as dependency. For example, SomeService will receive dbContext with connString to "someDb" and AnotherService will receive connString to "anotherDb". Commented Aug 29, 2018 at 8:11
  • You can create static variables for different connection strings and use it when needed like Singleton pattern. Otherwise if you do not know the connection names, then create a pool and fetch it from it if already present else create new entry in pool Commented Aug 29, 2018 at 8:11
  • 1
    May I ask what was the intend of your 'await Task.Run(() => ... )' ? I think that is just an unnecessary context switch there Commented Aug 29, 2018 at 8:27

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the reply. I wrote my methods this way but the problem is how can i do unit test for this type of methods. i can't write mock test for this method. i got stuck in here. I cant use a static dataset. i always have to use database. it's a bad way to do unit test.
@KSameera, You are using GetMemberList to get member list right? Do you want to send static data set from GetMemberList?
yes this method to get member list. For the unit test(mocking) i want send static dataset which not coming from database.
Then you should be using a mock class to provide these details right? I mean, there should be an interface IMemberDetails which will be inherited by both DB class and Mock class. Then you will use instance of Mock class to send details while testing. Right?
yes i want to use a instance of Mock class to send details while testing. That's why i need to change my method.
|
0

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;
    }
}

3 Comments

The problem is we use only one service. In the configuration file we can't use connection string this way. we have 30 clients. currently we have dynamic connection string and for these clients we have different databases. according to client we change the connection string.
How exactly does connection string depend on client?
Clients have different databases.We create connection with database for the different different client.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.