Autofac 构造函数链接

Autofac constructor chaining

我如何使用 Autofac 实现等效输出 123

我查看了以下内容,但我认为它不太符合我要实现的目标。

http://docs.autofac.org/en/latest/advanced/adapters-decorators.html

也许有人可以启发我-这是decorator吗?

using System;

namespace Prototypes.Decorator
{
    public class Program
    {
        static void Main()
        {
            new Class1(new Class2(new Class3(null))).Do();

            Console.ReadKey(true);
        }
    }

    public interface ICommand
    {
        void Do();
    }

    public abstract class BaseClass : ICommand
    {
        private readonly ICommand _command;

        protected BaseClass(ICommand command)
        {
            _command = command;
        }

        public abstract void Do();

        public void CallNext()
        {
            if (_command != null)
            {
                _command.Do();
            }
        }
    }

    public class Class1 : BaseClass
    {
        public Class1(ICommand command) : base(command)
        {
        }

        public override void Do()
        {
            Console.Write(1);

            CallNext();
        }
    }

    public class Class2 : BaseClass
    {
        public Class2(ICommand command) : base(command)
        {
        }

        public override void Do()
        {
            Console.Write(2);

            CallNext();
        }
    }

    public class Class3 : BaseClass
    {
        public Class3(ICommand command) : base(command)
        {
        }

        public override void Do()
        {
            Console.Write(3);

            CallNext();
        }
    }
}

如果在基础构造函数上有另一个接口怎么办呢?像 protected BaseClass(ICommand command, ILog log) { ... }

这样合理的东西

有多种方法可以构建您的容器以实现您的需要,您可以使用键控服务或 lambda。

Lambda 比使用字符串更不容易出错,所以这是一个简单的容器注册,可以满足您的需要:

ContainerBuilder cbLambdas = new ContainerBuilder();
cbLambdas.Register<Class3>(ctx => new Class3(null));
cbLambdas.Register<Class2>(ctx => new Class2(ctx.Resolve<Class3>()));
cbLambdas.Register<Class1>(ctx => new Class1(ctx.Resolve<Class2>()));

IContainer containerLambda = cbLambdas.Build();
containerLambda.Resolve<Class1>().Do();

如果添加ILog接口,按照如下声明:

public interface ILog
{
    void Log();
}

public class NullLog : ILog
{
    public void Log() { }
}

并将其添加为依赖项(在这种情况下仅适用于 Class2)

public class Class1 : BaseClass
{
    private readonly ILog logger;

    public Class1(ICommand command, ILog logger)
        : base(command)
    {
        this.logger = logger;
    }

    public override void Do()
    {
        Console.Write(1);
        CallNext();
    }
}

那么你的注册就变成了:

ContainerBuilder cbWithLog = new ContainerBuilder();
cbWithLog.RegisterType<NullLog>().As<ILog>();
cbWithLog.Register<Class3>(ctx => new Class3(null));
cbWithLog.Register<Class2>(ctx => new Class2(ctx.Resolve<Class3>()));
cbWithLog.Register<Class1>(ctx => new Class1(ctx.Resolve<Class2>(), ctx.Resolve<ILog>()));

IContainer containerLog = cbWithLog.Build();
containerLog.Resolve<Class1>().Do();