1

コードを使用して私の質問を説明しましょう。クラスがあります。

public class ComplexEntity
{
    private readonly ISomeDependency _someDependency;
    private readonly int _optionalArg;

    public ComplexEntity(ISomeDependency someDependency, int optionalArg)
    {
        _someDependency = someDependency;
        _optionalArg = optionalArg;
    }
}

およびモジュール:

public class FooModule : Module
{
    protected override void OnMap(ContainerBuilder builder)
    {
        builder.RegisterType<ConcreteDependency>().As<ISomeDependency>().SingleInstance();
        builder.RegisterType<ComplexEntity>().AsSelf();//SingleInstance fails my test below. 
    }
}

だから私の質問は-ComplexEntityオプションの引数(int型の-実際にはどの型でもかまいません)を使用して解決するにはどうすればよいですか?そのオプションの引数に従って、同じエンティティを返すか(すでに要求されている場合)、新しいものを作成します1つ-次のテストを見てください。

    int optionalArgument = 10;
    int anotherOptionalArgument = 11;

    //I expect ResolveOptional returns same references for the same optional argument, 
    //thus instance1 should be equals instance2, but not equals instance3
    var instance1 = _container.ResolveOptional<ComplexEntity>(
        new TypedParameter(optionalArgument.GetType(), optionalArgument));
    var instance2 = _container.ResolveOptional<ComplexEntity>(
        new TypedParameter(optionalArgument.GetType(), optionalArgument));

    var instance3 = _container.ResolveOptional<ComplexEntity>(
        new TypedParameter(anotherOptionalArgument.GetType(), anotherOptionalArgument));

    bool ref12Equals = object.ReferenceEquals(instance1, instance2); //should be true
    bool ref13Equals = object.ReferenceEquals(instance1, instance3); //should be false
    bool ref23Equals = object.ReferenceEquals(instance2, instance3); //should be false
4

1 に答える 1

0

autofac スコープでは、両方ではなく、シングルトンまたはファクトリ (一時的) のいずれかになります。より複雑なライフタイム管理が必要な場合は、その責任を負い、自分で管理する必要があると思います。私があなたを正しく理解していれば、新しいインスタンスを生成するか、シングルトンを返すスコープ マネージャーが必要です。それでも DI を使用したい場合は、次のようにコンテナーに入れることができます。

    private const int FactoryMode = 11;
    private const int SingletonMode = 10;

    public static void Main()
    {
        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterType<ComplexTypeScope>().SingleInstance();
        containerBuilder.Register((c, p) => c.Resolve<ComplexTypeScope>().Get(p.TypedAs<int>()));

        var container = containerBuilder.Build();
        ComplexType instance1 = container.Resolve<ComplexType>(new TypedParameter(typeof(int), SingletonMode));
        ComplexType instance2 = container.Resolve<ComplexType>(new TypedParameter(typeof(int), SingletonMode));
        ComplexType instance3 = container.Resolve<ComplexType>(new TypedParameter(typeof(int), FactoryMode));

        Debug.Assert(ReferenceEquals(instance1, instance2));
        Debug.Assert(!ReferenceEquals(instance1, instance3));
    }

    class ComplexType
    {
    }

    class ComplexTypeScope
    {
        private readonly Lazy<ComplexType> complexTypeSingleTon;

        public ComplexTypeScope()
        {
            complexTypeSingleTon = new Lazy<ComplexType>(() => new ComplexType());
        }

        public ComplexType Get(int parameter)
        {
            return parameter == FactoryMode ? new ComplexType() : complexTypeSingleTon.Value;
        }
    }

もちろん、このようなアプローチでは、コンテナは自動廃棄のようにコンポーネントの寿命を管理しません。

于 2013-05-22T08:57:25.097 に答える