繁体   English   中英

Unity ResolveAll,并解析未注册的类型

[英]Unity ResolveAll, and resolving unregistered types

简单的问题 ; 是否可以ResolveAll<T> ,对于未注册的类型?

在理想的世界中,我有类似于IPluggable接口的东西,当解析时会返回继承该接口的对象集合。

// both unregistered types
public class PluginOne : IPluggable { }
public class PluginTwo : IPluggable { }

// returns instances of PluginOne and PluginTwo
IEnumerable<IPluggable> result = container.ResolveAll<IPluggable>

据我所知,它可以通过StructureMap等替代方案实现,但遗憾的是我们的结构是围绕Unity构建的。 我能想到的唯一解决方案是创建一个引导程序,使用一些反射和命名空间挖掘自动注册某些类型?

是的,你是对的。 Unity不会解析任何未注册的类型(除非你要求单个类的实例而不是接口)。 提出的解决方案 - bootstrapper - 是我在许多项目中成功使用的解决方案。 我唯一的问题是选择要扫描的dll列表,如果你想让它在你的文件夹中找到扩展名,这可能会很棘手。 最省钱的方法是为此添加配置部分。

我创建了自己的扩展,根据我的界面IBlock解析类型。 扩展只在执行程序集中查找,但可能会在您想要的任何地方查找。 从这个角度来看,应该可以做出你想做的扩展。

I块:

using Microsoft.Practices.Unity;

public interface IBlock
{
    void Register(IUnityContainer unity);
}

延期:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Practices.Unity;

public class UnityBlockRegistrationExtender : UnityContainerExtension
{
    private readonly NameToTypesMap nameToTypesMap = new NameToTypesMap();

    protected override void Initialize()
    {
        var blockType = typeof(IBlock);
        var blockTypes = Assembly.GetEntryAssembly().GetTypes()
            .Where(block => blockType.IsAssignableFrom(block) && block.IsClass);
        foreach (var type in blockTypes)
        {
            if (this.nameToTypesMap.AddType(type.AssemblyQualifiedName, type))
            {
                var block = this.Container.Resolve(type) as IBlock;
                block.Register(this.Container);
            }
        }
    }

    private class NameToTypesMap
    {
        private readonly Dictionary<string, Type> map = new Dictionary<string, Type>();

        internal bool AddType(string name, Type type)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name", "A name is required.");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type", "A Type object is required.");
            }

            lock (this.map)
            {
                if (!this.map.ContainsKey(name))
                {
                    this.map[name] = type;
                    return true;
                }
            }

            return false;
        }
    }
}

Unity扩展与Structure Map的配置引擎非常相似。

它允许您扫描程序集以实现接口,并且还支持自定义约定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM