如何设置 Unity 注册约定
本文关键字:Unity 注册 约定 设置 何设置 | 更新日期: 2023-09-27 18:33:34
使用结构图,您可以注册一个约定,该约定不仅可以调整类型,还可以在对象创建期间进行干预。 如何使用 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);
});
}
}
}
你可以结合使用
Unity 的约定注册和 InjectionFactory 来做到这一点。 我看到了三种常见的实施选项,尽管我确信还有更多......
选项 1
使用 lambda 表达式中内联的 if 条件一次注册所有类型。 尽管如果您使用许多自定义注册注册许多类型,这不能很好地扩展......
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];
});
选项 2
仅注册 ISettings 类型并提供一些不错的帮助程序方法。 您将需要调用容器。多次注册类型,但它更具可读性...
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);
}
}
选项 3
或者,您可以创建一个派生自注册约定的类,并让该类做出所有注册决策......
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);
})
};
}
}