Comment puis-je injecter une chaîne de connexion dans une instance de IDbContextFactory & lt; T & gt ;?
Je suis en utilisant Entity Framework 5 avec le Premier Code Migrations. J'ai un DataStore
classe qui dérive de DbContext
:
public class DataStore : DbContext, IDataStore
{
public int UserID { get; private set; }
public DataStore(int userId, string connectionString) : base(connectionString)
{
UserID = userId;
}
public virtual IDbSet<User> Users { get; set; }
//Rest of code here
}
Et une usine de classe qui crée des instances de la DataStore
classe:
public class DataStoreFactory : Disposable, IDataStoreFactory
{
private DataStore _database;
private int _userId;
private string _connectionString;
public DataStoreFactory(int userId, string connectionString)
{
_userId = userId;
_connectionString = connectionString;
}
public IDataStore Get()
{
_database = new DataStore(_userId, _connectionString);
return _database;
}
protected override void DisposeCore()
{
if (_database != null) _database.Dispose();
}
}
Ces classes ont leurs les paramètres du constructeur injecté au moment de l'exécution avec L'unité. C'est très bien, tout fonctionne très bien!
Le problème se pose quand nous arrivons à les migrations: parce que mon DataStore
contexte de la classe ne possède pas de constructeur par défaut, j'ai besoin de fournir une implémentation de IDbContextFactory<T>
de sorte que le Premier Code des Migrations peut instancier:
public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
public DataStore Create()
{
//Need to inject connection string so we can pass it to this constructor
return new DataStore(0, "CONNECTION_STRING_NEEDED_HERE");
}
}
Le problème est que je ne peux pas comprendre comment je peux injecter de la chaîne de connexion dans cette classe. Je ne peux pas créer un nouveau constructeur avec un paramètre de chaîne de connexion comme ceci:
public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
public string _connectionString { get; set; }
public MigrationDataStoreFactory(string connectionString)
{
_connectionString = connectionString;
}
public DataStore Create()
{
return new DataStore(0, new DateTimeProvider(() => DateTime.Now), _connectionString);
}
}
Si je le fais, j'ai le exception levée par les Migrations à l'exécution:
[InvalidOperationException: The context factory type 'MigrationDataStoreFactory' must have a public default constructor.]
System.Data.Entity.Infrastructure.DbContextInfo.CreateActivator() +326
System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo) +106
System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType) +52
System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext) +202
System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) +66
System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context) +50
//Truncated stack trace, but you get the idea
A côté de cela, cette classe n'est pas instancié par l'Unité de toute façon, il semble juste être appelé par convention par le Premier Code Migrations en quelque sorte, alors même si je ne pouvais faire que ça ne serait pas vraiment aider...
Tout fonctionne bien si j'en dur dans le code la chaîne de connexion dans la méthode, mais je ne veux pas le faire, pour des raisons évidentes.
Quelqu'un peut-il aider s'il vous plaît?
source d'informationauteur Mark Bell
Vous devez vous connecter pour publier un commentaire.
Pour ceux pour qui la mise à niveau vers Entity Framework 6 est viable, il y a une nouvelle surcharge de la migration d'initialisation que cela rend beaucoup plus facile:
En utilisant cela, vous pouvez exécuter les migrations avec l'injection d'une DbContext comme suit:
Voici la démarche que j'ai finalement utilisé, à l'aide de la coutume
IDatabaseInitializer<T>
code de cette réponsequi m'a aidé beaucoup.Nous avons d'abord ajouter un autre constructeur de la
DataStore
classe (DbContext
) qui ne nécessite pas le paramètre de chaîne de connexion:Puis nous faisons la même chose pour l'usine de classe:
C'est la coutume de l'initialiseur de code:
Notre contexte personnalisé de l'usine (qui n'est jamais appelée par le Code des Premières Migrations) peuvent maintenant porter sur l'utilisation de la
DataStore
constructeur qui n'est pas nécessitent une chaîne de connexion:Aussi longtemps que nous avons mis l'initialiseur de base de données à notre coutume d'initialiseur et passer dans la chaîne de connexion (qui dans mon cas est fait dans
Global.asax
), les migrations vont utiliser la connexion correcte:De l'espoir à tout ce qui fait sens—n'hésitez pas à demander des précisions dans les commentaires.
D'abord définir vos paramètres de base de données de l'interface par exemple
IDBConnectionSettings
.Dans le
app.config
ajouter la chaîne de connexion:Pour récupérer la chaîne de connexion à partir de votre Paramètres fichier ou votre app.config vous avez besoin par exemple de faire:
Maintenant, vous devez vous inscrire à l'Interface quelque part dans votre code avant de l'utiliser.
Vous pouvez l'utiliser n'importe où à résoudre dans votre cas.
Mise à jour pour le constructeur par défaut
Faire une méthode statique ou mettre ce code dans le constructeur par défaut de cette façon, vous n'avez pas à donner toute params.
J'espère que cela permettra de résoudre votre problème! grâce