Autofac构造函数链接

时间:2015-06-12 17:14:14

标签: c# inversion-of-control decorator autofac

如何使用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) { ... }

的东西

1 个答案:

答案 0 :(得分:2)

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

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();