You can do this using a combination of Unity Convention Registration and InjectionFactory . I see three common implementation options, although I'm sure there are more ...
Option 1
Register all types at once if inline conditions are specified in a lambda expression. Although it doesn't scale very well if you register many types with many user registrations ...
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
Register only ISettings types and supply some useful helper methods. You will need to call container.RegisterTypes several times, but it is much more readable ...
container.RegisterTypes( AllClasses.FromLoadedAssemblies().IsSetting(), WithMappings.FromAllInterfaces, WithName.Default, WithLifetime.Transient, SettingsRegistration.InjectionMembers); ... public static class SettingsRegistration { public static IEnumerable<Type> IsSetting(this IEnumerable<Type> types) { return types.Where(type => !type.IsAbstract && typeof (ISettings).IsAssignableFrom(type)); } public static IEnumerable<InjectionMember> InjectionMembers(Type type) { return new[] {new InjectionFactory(LoadSetting)}; } public static ISettings LoadSetting(IUnityContainer container, Type type, string name) { var svc = (ISettings) container.Resolve(type, name); return svc.LoadSetting(type); } }
Option 3
Or you can create a class derived from RegistrationConvention and let this class make all registration decisions ...
container.RegisterTypes(new SettingsRegistrationConvention( AllClasses.FromLoadedAssemblies())); ... public class SettingsRegistrationConvention : RegistrationConvention { private readonly IEnumerable<Type> _scanTypes; public SettingsRegistrationConvention(IEnumerable<Type> scanTypes) { if (scanTypes == null) throw new ArgumentNullException("scanTypes"); _scanTypes = scanTypes; } public override IEnumerable<Type> GetTypes() { return _scanTypes.Where(type => !type.IsAbstract && typeof (ISettings).IsAssignableFrom(type)); } public override Func<Type, IEnumerable<Type>> GetFromTypes() { return WithMappings.FromAllInterfaces; } public override Func<Type, string> GetName() { return WithName.Default; } public override Func<Type, LifetimeManager> GetLifetimeManager() { return WithLifetime.Transient; } public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers() { return type => new[] { new InjectionFactory((c, t, n) => { var svc = (ISettings) c.Resolve(t); return svc.LoadSetting(t); }) }; } }