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に基づいてタイプを解決する独自の拡張機能を作成しました。拡張機能は実行中のアセンブリのみを検索しますが、必要な場所を検索できる可能性があります。これから、あなたが望むことをする拡張を作ることが可能であるはずです。

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

Structure Map の構成エンジンと非常によく似た、Unity 用の拡張機能があります。

これにより、アセンブリをスキャンしてインターフェイスの実装を見つけることができ、カスタム規則もサポートされます。

于 2013-01-08T11:31:49.013 に答える