使用结构图,您可以注册一个约定,它不仅可以调整类型,还可以在创建对象时进行干预。我怎么能用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<ISettingService>();
return svc.LoadSetting(type);
});
}
}
}
答案 0 :(得分:14)
您可以结合使用Unity Registration by Convention和InjectionFactory来完成此操作。我看到了三种常见的实施方案,但我确信还有更多......
如果条件内联在lambda表达式中,则一次注册所有类型。如果您注册许多具有许多自定义注册的类型,这不能很好地扩展...
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];
});
仅注册ISettings类型并提供一些不错的帮助方法。您需要多次调用container.RegisterTypes,但它更具可读性......
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);
}
}
或者你可以创建一个派生自RegistrationConvention的类,让该类做出所有的注册决定......
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);
})
};
}
}