5

Je suis en train d'utiliser l'unité pour injecter automatiquement un datacontext sur mon dépôt en utilisant une nouvelle instance à chaque fois .., mon idée est faire en sorte que chaque fois qu'un nouveau DataContext est injectéUNITY: transmettre un nouveau datacontext à chaque fois?

Actuellement son échec sur la création du référentiel, je pense qu'il ne peut pas résoudre MyDataContext

Avant de créer un constructeur sur « le référentiel » (voir ci-dessous) pour prendre en DataContext sur mon tout dépôt de travail mais maintenant son échec ..

J'ai actuellement cette configuration dans mon conteneur d'unité que je crée dans global.asax, j'ai aussi enregistré le type MyDataContext qui est standard DataContext

 container = new UnityContainer(); 

     Container.RegisterType<MyDataContext, MyDataContext>() 
      .RegisterType<IOfficeRepository, OfficeRepository>() 
      .RegisterType<IOfficeService, OfficeService>(); 

essentiellement j'ai un service qui appelle le dépôt comme si

public class OfficeService : IOfficeService 
{ 

    IOfficeRepository repository = null; 

    public OfficeService(IOfficeRepository repository) 
    { 
     this.repository = repository; 

     if (this.repository == null) 
      throw new InvalidOperationException("Repository cannot be null"); 
    } 

ici est mon dépôt

public class OfficeRepository : IOfficeRepository 
{ 
    private MyDataContext db; 

    public OfficeRepository (MyDataContext dataContext) 
    { 
     this.db = dataContext; 
    } 

EDIT

J'ai presque oublié que je suis en train de faire ce pour créer le service

officeService = Bootstrapper.Container.Resolve<IOfficeService>(); 

EDIT - L'ERREUR générée

Resolution of the dependency failed, type = "MarkSmith.IOfficeService", name = "". 
Exception message is: The current build operation (build key Build 
Key[MarkSmith.OfficeService, null]) failed: The parameter repository could not be 
resolved when attempting to call constructor 
MarkSmith.OfficeService(MarkSmith.IOfficeRepository repository). (Strategy type BuildPlanStrategy, index 3) 

EDIT - ENLEVER Constructor sur référentiel fonctionne

Il est quelque chose à voir avec le datacontext parce que si je retire la constrcutor sur la référentiel qui prend un DataContext alors tout fonctionne, mais bien sûr j'en ai besoin pour accepter un DataContext pour pouvoir injecter un "nouveau" datacontext à chaque fois

public class OfficeRepository : IOfficeRepository 
{ 
    private MyDataContext db new MyDataContext(); // CHANGE 

    //public OfficeRepository (MyDataContext dataContext) 
    //{ 
     //this.db = dataContext; 
    //} 

EDIT - ERREUR RÉEL

Après avoir creusé plus profond que j'ai trouvé cette erreur ....

The type MyDataContext has multiple constructors of length 2. 
Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) 
(Strategy type BuildPlanStrategy, index 3) 

EDIT - TEST POUR RÉSOUDRE DataContext avec 1 ligne de code

Cela échoue également avec la même erreur que ci-dessus - plusieurs constructeurs

MyDataContext test = Bootstrapper.Container.Resolve<MyDataContext >(); 

EDIT - CONSTRUCTEURS SUR MON TOUS datacontext

Ils ont été créés par un exernal util mais tous devraient être bien ..

[System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext() 
     : base(ConnectionString, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(string connection) 
     : base(connection, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(System.Data.IDbConnection connection) 
     : base(connection, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) 
     : base(connection, mappingSource) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) 
     : base(connection, mappingSource) 
    { 
     OnCreated(); 
    } 

EDIT - Pour démontrer la création du DataContext dans le code sans unité fonctionne 100% sans problème

MyDataContext tes2t = new MyDataContext(); 
+0

Question mise à jour pour montrer comment je résous mon service en utilisant l'unité –

+0

Que se passe-t-il si vous tentez de résoudre une instance de MyDataContext à différents endroits? Tout semble être en ordre, mais cela peut nous donner une idée. – GraemeF

+0

De plus, y a-t-il une ligne ou une faute de frappe manquante dans le premier extrait de code? Il semble que 'container' et' Container' seraient des instances différentes. Vous pouvez vérifier que vous avez l'instance que vous attendez en utilisant le débogueur. – GraemeF

Répondre

10

Je ne suis pas sûr que cela fonctionne, mais avez-vous essayé d'enregistrer MyDataContext en tant que composant plutôt qu'un mappage de type?

container.RegisterType<MyDataContext>(); 

au lieu de

container.RegisterType<MyDataContext, MyDataContext>(); 

EDIT sur la base de nouvelles informations

Le coupable semble être que MyDataContext a plus d'un constructeur. C'est un problème commun avec la plupart des conteneurs DI, car ils doivent choisir et utiliser un seul. Si vous pouvez supprimer l'ambiguïté en contraignant MyDataContext à avoir un seul constructeur, ce sera probablement la solution la plus simple. Dans le cas contraire, vous devriez pouvoir utiliser une instance d'InjectionConstructor pour identifier le constructeur lorsque vous enregistrez le référentiel. Supposons que vous voulez utiliser un constructeur qui prend une chaîne de connexion comme argument:

string connectionString = 
    ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString; 
var injectedConnectionString = new InjectionConstructor(connectionString); 
container.RegisterType<MyDataContext>(injectedConnectionString); 
+0

Merci Mark, j'ai essayé et c'est la même chose. J'ai mis à jour ma question avec l'erreur spécifique .. –

+0

La question mise à jour montre également comment supprimer les travaux du constructeur mais bien sûr j'ai besoin du constructeur pour accepter un DataContext - des idées? –

+0

Voir ma réponse mise à jour. –

1

Je ne vois pas vos constructeurs de MyDataContext; mais essayez d'ajouter l'attribut [InjectionConstructor] à celui que vous voulez utiliser.

+1

Cela devrait fonctionner, mais va étroitement coupler MyDataContext à Unity. –

+0

Cet infaillible fonctionne !!! Mais comme l'a souligné Mark, son couplage étroit et mon datacontext sont créés par un util externe, donc l'attribut serait écrasé ... Je ne comprends vraiment pas pourquoi l'unité a un problème, je ne suis pas intéressé par un constructeur (c'est-à-dire des constructeurs avec 2 tabliers) je ne m'intéresse qu'au constructeur param zéro et bien sur il n'y en a qu'un ... Y at-il une alternative ??? –

3

Avec plusieurs constructeurs parmi lesquels choisir, Unity ne sait pas lequel utiliser. Il choisira celui avec le plus d'arguments qui peuvent tous être satisfaits, mais dans ce cas il y a deux constructeurs chacun avec deux arguments résolvables.

Si vous ne voulez pas coupler votre MyDataContext classe à l'unité et d'utiliser l'attribut InjectionConstructor comme suggéré par Scott (upvoted :)), vous pouvez spécifier le constructeur qui doit être utilisé au moment de l'enregistrement à l'aide de l'interface fluide . Voir Configuring Constructor, Property, and Method Injection pour plus de détails.

+0

Merci GraemeF, c'est une grande info .. Merci pour votre aide .. –