1

今日、オプションの依存関係 (私の場合はロガー インスタンス) のプロパティ注入と組み合わせて、型の複数の実装を解決することに関して、一見奇妙な問題に遭遇しました。

規約に基づいた構成を実現するために、Unity 2.1 と UnityConfiguration を使用しています。

ILoggerの実装を多くの型に挿入するために、 SetAllPropertiesConventionを使用しています。

container.Resolve<IProcessor>()たとえば、ILogger のインスタンスを使用して単一の実装を解決している場合、適切に注入されます。

container.ResolveAll<IProcessor>()ただし、プロパティを使用してそのタイプの複数のインスタンスを解決している場合は、 null のままです。

ここに私の登録コード:

container.RegisterInstance(typeof (ILogger), LoggerService.GetLogger());
container.Configure(c => c.Scan(scan =>
                    {
                        scan.AssembliesInBaseDirectory(a => a.FullName.StartsWith("My.Company"));
                        scan.InternalTypes();
                        scan.With<AddAllConvention>().TypesImplementing<IFetchDataCommand>();
                        scan.With<AddAllConvention>().TypesImplementing<IPrintConverter>();
                        scan.With<SetAllPropertiesConvention>().OfType<ILogger>();
                    }));

SetAllPropertiesConvention自体は、次のコードを使用して、注入されたロガー es プロパティを登録します。

IEnumerable<PropertyInfo> properties =
                type.GetProperties().Where(p => p.CanWrite && p.PropertyType == interfaceType);

foreach (PropertyInfo property in properties)
{
    registry.Register(null, type).WithInjectionMembers(new InjectionProperty(property.Name));
}

これはバグですか、それとも何か間違っていましたか。何か案は?

4

1 に答える 1

1

メソッドを使用しRegisterType<T, U>()てパラメーターなしで依存関係を登録している場合、別の実装を登録することはありません。次のように、名前付き登録を提供する必要があります。

RegisterType<IProcessor, MyProcessor1>("MyProcessor1")
RegisterType<IProcessor, MyProcessor2>("MyProcessor2")

ResolveAll()名前のないマッピングは含まれません。

編集:

規則を使用してプロパティ注入を構成できない理由はわかりませんが、型が構築された後に設定できます。このようなもの:

    var container = new UnityContainer();
    container.RegisterInstance(typeof (ILogger), new Logger());

    container.Configure(x => 
        {
            x.AfterBuildingUp<IFetchDataCommand>().Call((c,s) => s.Logger = c.Resolve<ILogger>());
            x.Scan(
                scan =>
                    {
                        scan.Assembly(Assembly.GetExecutingAssembly());
                        scan.InternalTypes();
                        scan.With<AddAllConvention>().TypesImplementing<IFetchDataCommand>();
                        scan.WithSetAllPropertiesConvention().OfType<ILogger>();
                    });
        });

    var dataCommand = container.ResolveAll<IFetchDataCommand>().ToArray();

    Assert.That(dataCommand[0].Logger, Is.Not.Null);
    Assert.That(dataCommand[1].Logger, Is.Not.Null);

この行は重要です:

x.AfterBuildingUp<IFetchDataCommand>().Call((c,s) => s.Logger = c.Resolve<ILogger>());

そして私のクラス:

public interface IDataCommand
{
    ILogger Logger { get; set; }
}

public class Logger : ILogger
{
    public string Name { get; set; }
}

public class FetchDataCommand : IDataCommand
{
    public ILogger Logger { get; set; }
}

public class StoreDataCommand : IDataCommand
{
    public ILogger Logger { get; set; }
}
于 2013-04-24T19:45:51.923 に答える