1

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

4

3 回答 3

2

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

于 2013-01-08T11:06:33.430 回答
1

我创建了自己的扩展,它根据我的接口 IBlock 解析类型。该扩展仅查看正在执行的程序集,但可能会查看您想要的任何位置。从这里应该可以做一个你想要的扩展。

块:

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;
        }
    }
}
于 2013-01-10T11:12:14.443 回答
0

Unity有一个扩展,其工作方式与 Structure Map 的配置引擎非常相似。

它允许您扫描程序集以查找接口的实现,并为您提供对自定义约定的支持。

于 2013-01-08T11:31:49.013 回答