Comment mettre en place une convention d’enregistrement Unity?

Avec la structure de structure, vous pouvez enregistrer une convention qui vous permet non seulement d’affiner le type, mais également d’intervenir lors de la création d’un object. Comment puis-je faire cela avec Unity.

public class SettingsRegistration : IRegistrationConvention { public void Process(Type type, Registry registry) { if (!type.IsAbstract && typeof(ISettings).IsAssignableFrom(type)) { registry.For(type).Use(x => { var svc = x.GetInstance(); return svc.LoadSetting(type); }); } } } 

Vous pouvez le faire avec une combinaison d’ Enregistrement par convention d’Unity et d’une InjectionFactory . Je vois trois options communes pour la mise en œuvre, même si je suis sûr qu’il y a plus …


Option 1

Enregistrez tous les types en même temps avec les conditions if inline dans une expression lambda. Bien que cela ne se fasse pas bien si vous enregistrez plusieurs types avec de nombreux enregistrements personnalisés …

 container.RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromAllInterfaces, WithName.Default, WithLifetime.Transient, type => { // If settings type, load the setting if (!type.IsAbstract && typeof (ISettings).IsAssignableFrom(type)) { return new[] { new InjectionFactory((c, t, n) => { var svc = (ISettings) c.Resolve(t); return svc.LoadSetting(t); }) }; } // Otherwise, no special consideration is needed return new InjectionMember[0]; }); 

Option 2

Enregistrez uniquement les types ISettings et fournissez quelques méthodes d’assistance intéressantes. Vous devrez appeler container.RegisterTypes plusieurs fois, mais il est beaucoup plus lisible …

 container.RegisterTypes( AllClasses.FromLoadedAssemblies().IsSetting(), WithMappings.FromAllInterfaces, WithName.Default, WithLifetime.Transient, SettingsRegistration.InjectionMembers); ... public static class SettingsRegistration { public static IEnumerable IsSetting(this IEnumerable types) { return types.Where(type => !type.IsAbstract && typeof (ISettings).IsAssignableFrom(type)); } public static IEnumerable InjectionMembers(Type type) { return new[] {new InjectionFactory(LoadSetting)}; } public static ISettings LoadSetting(IUnityContainer container, Type type, ssortingng name) { var svc = (ISettings) container.Resolve(type, name); return svc.LoadSetting(type); } } 

Option 3

Ou vous pouvez créer une classe dérivée de RegistrationConvention et laisser cette classe prendre toutes les décisions d’enregistrement …

 container.RegisterTypes(new SettingsRegistrationConvention( AllClasses.FromLoadedAssemblies())); ... public class SettingsRegistrationConvention : RegistrationConvention { private readonly IEnumerable _scanTypes; public SettingsRegistrationConvention(IEnumerable scanTypes) { if (scanTypes == null) throw new ArgumentNullException("scanTypes"); _scanTypes = scanTypes; } public override IEnumerable GetTypes() { return _scanTypes.Where(type => !type.IsAbstract && typeof (ISettings).IsAssignableFrom(type)); } public override Func> GetFromTypes() { return WithMappings.FromAllInterfaces; } public override Func GetName() { return WithName.Default; } public override Func GetLifetimeManager() { return WithLifetime.Transient; } public override Func> GetInjectionMembers() { return type => new[] { new InjectionFactory((c, t, n) => { var svc = (ISettings) c.Resolve(t); return svc.LoadSetting(t); }) }; } }