2010-01-15 3 views
0

Il y a quelques questions sur SO à propos de StructureMap et des génériques, et j'ai lu quelques articles de blog à ce sujet, mais j'ai encore du mal à trouver la solution à ce scénario particulier.Câblage des interfaces génériques dans StructureMap

Étant donné:

public interface ILookup 
{ 
} 

public interface ISupplier : ILookup 
{ 
} 

public interface ITenant : ILookup 
{ 
} 

public class Supplier : ISupplier 
{ 
} 

public class Tenant : ITenant 
{ 
} 

public interface ILookupRepository<TLookup> where TLookup : ILookup 
{ 
    void DoSomethingWith(TLookup lookup); 
} 

public class LookupRepository<TLookup> : ILookupRepository<TLookup> where TLookup : ILookup 
{ 
    public void DoSomethingWith(TLookup lookup) 
    { 
     SaveOrWhatever(lookup); 
    } 
} 

public class SomeClass 
{ 
    public void ProcessLookup(ILookup lookup) 
    { 
     // Get hold of a concrete class for ILookupRepository<TLookup> where TLookup is the type of the supplied 
     // lookup. For example, if ProcessLookup is passed an ISupplier I want a LookupRepository<ISupplier>. 
     // If it's passed an ITenant I want a LookupRepository<ITenant>. 

     // var repository = ??? 

     repository.DoSomethingWith(lookup); 
    } 
} 

Comment puis-je obtenir StructureMap pour fournir SomeClass.ProcessLookup avec le LookupRepository<ISupplier> ou LookupRepository<ITenant> correspondant? Est-ce possible sans réflexion? Puis-je avoir un LookupRepository<Supplier> ou LookupRepository<Tenant> à la place?

Mise à jour:

Après avoir lu la réponse initiale de Richard, je me suis rendu compte que ma première question n'a pas exprimé très bien mon problème (c'est vendredi après tout!). Je fais face à plus d'une implémentation de ILookup et je veux pouvoir obtenir le bon ILookupRepository pour le type que je fournis. J'ai mis à jour la question ci-dessus pour mieux refléter mes besoins.

Mise à jour 2:

Le besoin immédiat de se fissurer ce qui a passé que nous avons adopté une approche légèrement différente. Cependant, je suis toujours intéressé à entendre des suggestions supplémentaires à Richard.

Répondre

1

[Modifié que les réponses initiales ne répondaient pas la vraie question]

Quand j'ai besoin de faire quelque chose de semblable, j'utilise les instances nommées. Malheureusement, je ne vois pas de moyen facile de faire ce dont vous avez besoin sans introduire une interface non générique. L'interface non générique ressemblerait à ceci (et serait heureusement pas réellement public):

public interface ILookupRepository 
{ 
    void DoSomethingWith(object lookup); 
} 

Marque ILookupRepository héritera de l'interface ILookupRegistry non générique. Puis, en StructureMap vous 2.5.4 pourriez faire quelque chose comme ceci:

For<ILookupRepository>().Add<LookupRepository<Supplier>>() 
    .Named(typeof(Supplier).FullName); 
For<ILookupRepository>().Add<LookupRepository<Tenant>>() 
    .Named(typeof(Tenant).FullName); 

ensuite obtenir le dépôt de recherche dans votre méthode utilisant

var repo = ObjectFactory.GetInstance<ILookupRepository>(lookup.GetType().FullName); 

NOTE: Il est peut-être mieux (si possible) si l'interface iLookup fournit le mécanisme pour déterminer le type. Par exemple. le locataire concret (ou tout ce qui en hérite) retournera "ITenant", permettant au même référentiel de recherche d'être réutilisé le cas échéant.

Cela aide-t-il maintenant?

+0

Merci pour votre réponse. Je pense que j'aurais dû être plus clair que j'étais dans ma question car cela n'aide pas malheureusement. Je vais mettre à jour ma question avec plus d'informations. –

+0

J'ai aussi mis à jour ma réponse ... Je ne suis pas vraiment content (il y a probablement une meilleure solution), mais cela peut vous orienter dans la bonne direction. –

+0

Cela donne matière à réflexion, merci. –

Questions connexes