Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify connection string when using db context

I am using the Repository pattern for EF and have ran into a problem in that I cannot figure out how to set the connection string for the DbContext through a variable. Currently my constructor is parameterless (it has to be to fit with he pattern) i.e.

IUnitOfWork uow = new UnitOfWork<EMDataContext>();
DeviceService deviceService = new DeviceService(uow);
var what = deviceService.GetAllDevices();


public UnitOfWork()
{
    _ctx = new TContext();
    _repositories = new Dictionary<Type, object>();
    _disposed = false;
}

EMDataContext used to take a string in its constructor to define the ConnectionString but can no longer do that so how do I actually tell the EMDataContext what to connect to when its created in this fashion?

like image 712
Chris Avatar asked Oct 21 '22 02:10

Chris


1 Answers

Your question can be rewritten as "How to pass an argument to a generic type constructor with a new() constraint".

From MSDN:

The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor.

Since the bare Entity Framework context doesn't contain a parameter-less constructor, I assume your EMDataContext is your custom context that derives from it:

public class EMDataContext : DbContext
{
      // parameterless ctor, since you're using new() in UnitOfWork<TContext>
      public EMDataContext() : base(???)
      {
      }

      public EMDataContext(string connectionString) : base(connectionString)
      {
      }
}

Now, I would argue that your EMDataContext is incapable of having a parameter-less constructor, hence incapable of the new() constraint as well, especially when you're saying that you do want to pass a connection-string parameter.

Try to change your UnitOfWork to accept an already-initialized context in it's constructor (common pattern):

public class UnitOfWork<TContext>
{
    public UnitOfWork(TContext ctx)
    {
        _ctx = ctx;
    }
}

Alternatively (if you still want to "fit the pattern"), try to instantiate the context using Activator:

public class UnitOfWork<TContext>
{
    public UnitOfWork(string connectionString)
    {
        _ctx = (TContext)Activator.CreateInstance(typeof(TContext), new[] { connectionString });
    }
}
like image 132
haim770 Avatar answered Oct 23 '22 19:10

haim770