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

时间:2013-01-08 10:58:33

标签: c# unity-container

简单的问题;对于未注册的类型,是否可以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构建的。我能想到的唯一解决方案是创建一个引导程序,使用一些反射和命名空间挖掘自动注册某些类型?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我创建了自己的扩展,根据我的界面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;
        }
    }
}

答案 2 :(得分:0)

有一个extension for Unity与Structure Map的配置引擎非常相似。

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