Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use an internal DbContext?

How to use an internal DbContext? I wonder how can I hide the DbContext object so that other libraries of my project not directly access.

I put my DbContext as internal in the library, and apparently should work, however when I run the application, the following error appears:

The target context 'Context' is not constructible. Add a default constructor or Provide an Implementation of IDbContextFactory

Could someone help me?

My implementation of data layer is:

[DbConfigurationType(typeof (ConfigContext))]
internal class Context : DbContext
{
    internal Context()
        : base(ConfigDataBase.GetSqlServerString(ConfigZnfce.Instance.SqlServerInstance))
    {
    }
    //More code below
}


public class ConfigContext: DbConfiguration
{
    public ConfigContext()
    {
        SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.LocalDbConnectionFactory("v11.0"));
        SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
        SetDatabaseInitializer(new CreateDatabaseIfNotExists<Context>());
        SetDatabaseInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());            
    }
}

I want all the other libraries are required to go through a unit of work and repositories in order to do any operation with the database

[SOLVED]

I left the Context class as "internal" and set the constructor as "public" as in the code below:

[DbConfigurationType(typeof (ConfigContext))]
internal class Context : DbContext
{
    public Context()
        : base(ConfigDataBase.GetSqlServerString(ConfigZnfce.Instance.SqlServerInstance))
    {
    }
    //More code below
}
like image 885
Zeus-Adenilton Avatar asked Oct 19 '22 16:10

Zeus-Adenilton


1 Answers

The virtual DBSet<> properties on the DbContext class must be public (as you found out in your solution.

If you're using TT templates, you can make this happen by changing the DbSet(EntitySet entitySet) function. Notice that the term public replaces the original {0} parameter in the string format.

public string DbSet(EntitySet entitySet) {
    return string.Format(
        CultureInfo.InvariantCulture,
        "public virtual DbSet<{0}> {1} {{ get; set; }}",
        _typeMapper.GetTypeName(entitySet.ElementType),
        _code.Escape(entitySet));
}

Now, you can have an internal DbContext, internal objects, and still have the public automatic properties so EF can do its data-binding.

like image 120
Chad Greer Avatar answered Oct 22 '22 07:10

Chad Greer