如何设置Unity注册约定? [英] How to setup a Unity Registration Convention?

查看:47
本文介绍了如何设置Unity注册约定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用结构图,您可以注册一个约定,该约定不仅可以调整类型,还可以在对象创建期间进行干预。

With structure map, you can register a convention that lets you not just tweak the type, but also intervene during object creation. How can I do this with 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 。我看到了三个常见的实施选项,尽管我确定还有更多...

You can do this with a combination of Unity's Registration by Convention and an InjectionFactory. I see three common options for implementation, though I'm sure there are more...

如果条件在lambda表达式中内联,则立即注册所有类型。虽然如果您要通过许多自定义注册来注册许多类型,这种方法的伸缩性不好。

Register all type at once with if conditions inline in a lambda expression. Though this does not scale well if you are registering many types with many custom 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];
    });






选项2



仅注册ISettings类型并提供一些不错的帮助器方法。您将需要多次调用container.RegisterTypes,但是它更具可读性...


Option 2

Register only the ISettings types and supply some nice helper methods. You will need to call container.RegisterTypes multiple 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);
    }
}






选项3



或者您可以创建一个从RegistrationConvention派生的类,然后让该类做出所有注册决定...


Option 3

Or you could create a class derived from RegistrationConvention and let that class make all of the 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);
            })
        };
    }
}

这篇关于如何设置Unity注册约定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆