如何设置 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 注册约定

你可以结合使用

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);
            })
        };
    }
}