Sì, è necessario utilizzare la riflessione su facilmente creare tutti i mapping che si desidera. Poiché stai utilizzando Unity 3, puoi sfruttare Registration by Convention per fornire assistenza (con il sollevamento più pesante) nella registrazione delle classi.
ho preso il codice pseudo e tradotto in codice vero e proprio:
public abstract class BaseClass
{
public abstract void DoFoo();
}
public class ClassNumber001 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("001 Foo");
}
}
public class ClassNumber002 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("002 Foo");
}
}
public interface ISuperman
{
void Do();
}
public class Superman<T> : ISuperman where T : BaseClass
{
private T baseClass;
public Superman(T baseClass)
{
this.baseClass = baseClass;
}
public void Do()
{
this.baseClass.DoFoo();
}
}
public class MainViewModel
{
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
foreach(ISuperman superman in lotsofSuperman)
{
superman.Do();
}
}
}
Quindi utilizzare registrazione per convenzione di registrare tutti i farmaci generici:
IUnityContainer container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t))
.Select(t => typeof(Superman<>).MakeGenericType(t)),
t => new Type[] { typeof(ISuperman) },
t => t.GetGenericArguments().First().Name,
WithLifetime.Transient);
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
container.Resolve<MainViewModel>();
Nel codice di cui sopra si ottengono tutti le classi che ereditano da BaseClass
e poi costruire un tipo Superman<>
e mappa che a ISuperman
utilizzando il nome del BaseClass
.La chiamata registerTypes sarà equivalente a RegisterType chiedendo ogni BaseClass:
container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001");
container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002");
Poi, quando MainViewModel
si risolve si itera su tutte le ISuperman
le istanze e chiama un metodo che stampa:
001 Foo
002 foo
mostrando che abbiamo iniettato 2 ISuperman
casi: Superman<ClassNumber001>
e Superman<ClassNumber002>
.
Se sono necessarie registrazioni specifiche per le BaseClasses (ad esempio un gestore di durata non predefinita), è possibile utilizzare la registrazione per convenzione per registrare anche quelle).
fonte
2015-07-15 18:38:41
È obbligatorio farlo per riflessione? Quale versione di Unity stai usando, sopra 3.x? – gastonmancini
No, non è obbligatorio, ho menzionato il riflesso perché l'ho usato prima. (per trovare tutte le classi 300) Uso Unity 3.5.1404.0. – Tim