Dies ist eine sehr späte Antwort, aber die Frage wird immer noch in Google angezeigt.
Also sowieso 5 Jahre später ...
Ich habe einen ziemlich einfachen Ansatz. Wenn Sie "benannte Abhängigkeit" verwenden müssen, liegt dies normalerweise daran, dass Sie versuchen, eine Art Strategiemuster zu implementieren. In diesem Fall erstelle ich einfach eine Indirektionsebene zwischen Unity und dem Rest meines Codes, die StrategyResolver
als nicht direkt von Unity abhängig bezeichnet wird.
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
Verwendung:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Anmeldung:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Das Schöne daran ist, dass ich den StrategyResolver nie wieder berühren muss, wenn ich in Zukunft neue Strategien hinzufüge.
Es ist sehr einfach. Sehr sauber und ich habe die Abhängigkeit von Unity auf ein striktes Minimum beschränkt. Das einzige Mal, dass ich den StrategyResolver berühren müsste, wäre, wenn ich mich entscheide, die Containertechnologie zu ändern, was sehr unwahrscheinlich ist.
Hoffe das hilft!
Bearbeiten: Die akzeptierte Antwort gefällt mir nicht wirklich, da Sie bei Verwendung des Dependency
Attributs im Konstruktor Ihres Dienstes tatsächlich eine starke Abhängigkeit von Unity haben. Das Dependency
Attribut ist Teil der Unity-Bibliothek. An diesem Punkt können Sie genauso gut IUnityContainer
überall eine Abhängigkeit übergeben.
Ich bevorzuge es, wenn meine Serviceklassen von Objekten abhängen, die ich vollständig besitze, anstatt überall stark von einer externen Bibliothek abhängig zu sein. Durch die Verwendung von Dependency
Attributen werden die Konstruktorsignaturen weniger sauber und einfach.
Darüber hinaus ermöglicht diese Technik das Auflösen benannter Abhängigkeiten zur Laufzeit, ohne die benannten Abhängigkeiten im Konstruktor, in der Anwendungskonfigurationsdatei oder in der Verwendung fest codieren zu müssen. Dies InjectionParameter
sind alles Methoden, die wissen müssen, welche benannte Abhängigkeit zur Entwurfszeit verwendet werden soll.
Bearbeiten (19.09.2016): Für diejenigen, die sich fragen könnten, weiß der Container, dass er sich selbst übergeben muss, wenn Sie eine IUnityContainer
Abhängigkeit anfordern , wie in der StrategyResolver
Konstruktorsignatur gezeigt .
Bearbeiten (20.10.2018): Hier ist eine andere Möglichkeit, einfach eine Factory zu verwenden:
public class SomeStrategyFactory : ISomeStrategyFactory
{
private IStrategy _stratA;
private IStrategy _stratB;
public SomeFactory(IStrategyA stratA, IStrategyB stratB)
{
_stratA = stratA;
_stratB = stratB;
}
public IStrategy GetStrategy(string namedStrategy){
if (namedStrategy == "A") return _stratA;
if (namedStrategy == "B") return _stratB;
}
}
public interface IStrategy {
void Execute();
}
public interface IStrategyA : IStrategy {}
public interface IStrategyB : IStrategy {}
public class StrategyA : IStrategyA {
public void Execute(){}
}
public class StrategyB : IStrategyB {
public void Execute() {}
}
Verwendung:
public class SomeClass : ISomeClass
{
public SomeClass(ISomeStrategyFactory strategyFactory){
IStrategy strat = strategyFactory.GetStrategy("HelloStrategy");
strat.Execute();
}
}
Anmeldung:
container.RegisterType<ISomeStrategyFactory, SomeStrategyFactory>();
container.RegisterType<IStrategyA, StrategyA>();
container.RegisterType<IStrategyB, StrategyB>();
container.RegisterType<ISomeClass, SomeClass>();
Dieser zweite Vorschlag ist dasselbe, verwendet jedoch das werkseitige Entwurfsmuster.
Hoffe das hilft!
IRepository>("Customer")
sollte das in einer anderen Instanz vonClientModel