Penso che la gestione della durata dovrebbe essere parte dell'applicazione stessa e non delle librerie di classi. Spetta all'applicazione decidere in merito nel Root di composizione .
Detto questo, ecco una soluzione che puoi utilizzare con il contenitore Unity :
Crea alcuni attributi personalizzati per i diversi stili di durata che desideri avere in questo modo:
[AttributeUsage(AttributeTargets.Class)]
public class SingletonAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class TransientAttribute : Attribute
{
}
Puoi avere questi attributi in alcune librerie comuni e fare riferimento alle tue librerie di classi di servizio.
Quindi applica questi attributi alle tue classi di servizio nelle tue librerie di classi come nella tua domanda:
[Singleton]
public class ServiceImplA : IService
{}
[Transient]
public class ServiceImplB : IService
{}
Ora, definisci un metodo di supporto che possa ottenere il lifetime manager basato sulla riflessione in questo modo:
public static LifetimeManager GetLifeTimeManager<T>()
{
Type type = typeof (T);
if(type.GetCustomAttribute(typeof(TransientAttribute)) != null)
return new TransientLifetimeManager();
if (type.GetCustomAttribute(typeof(SingletonAttribute)) != null)
return new ContainerControlledLifetimeManager();
//Add more cases here
return new TransientLifetimeManager(); //Default is transient
}
E usalo in questo modo:
container.RegisterType<IService, ServiceImplA>(GetLifeTimeManager<ServiceImplA>());
A proposito, questa soluzione è indipendente dal contenitore DI. Intendo dire che gli attributi stessi non sono specifici per alcun contenitore. È il metodo helper GetLifeTimeManager
specifico per il contenitore Unity. Ma puoi usare altri contenitori DI e definire metodi di supporto simili per loro.
Puoi anche creare metodi di estensione per nascondere la chiamata del metodo helper in questo modo:
public static IUnityContainer RegisterTypeWithLifeTime<TFrom, TTo>(this IUnityContainer container) where TTo : TFrom
{
return container.RegisterType<TFrom, TTo>(GetLifeTimeManager<TTo>());
}
E usalo in questo modo:
container.RegisterTypeWithLifeTime<IService, ServiceImplA>();