Castle Windsor传播内联依赖项

时间:2016-12-02 12:08:16

标签: dependency-injection castle-windsor

我正在尝试实现对象构造,如下所示,

using (var context = new DbContext())
{
    var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
}

但使用Castle Windsor。我正在使用内联依赖项,如下面的代码所示,但正如Castle Windsor文档所述,“内联依赖项不会传播”Castle Windsor passing arguments。我怎样才能实现另一种方式?

using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;

namespace IOCTesting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new DbContext())
            {
                var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
            }

            var container = new WindsorContainer();

            container
                .Register(Component.For<IProcessor>()
                .ImplementedBy<Processor>());

            container
                .Register(Component.For<IParser>()
                .ImplementedBy<Parser>());

            container
                .Register(Component.For<ILogger>()
                .ImplementedBy<Logger>());


            //[1] Creating my scope object here. (context)
            using (var context = new DbContext())
            {
                var processor = container.Resolve<IProcessor>(new { context = context });
            }
        }
    }

    public class DbContext : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("DbContext disposed.");
        }
    }

    public class Processor : IProcessor
    {
        private readonly DbContext _context;
        private readonly ILogger _logger;
        private readonly IParser _parser;

        //Dependency context passed in is the same object within the scope. See [1]
        public Processor(DbContext context, IParser parser, ILogger logger)
        {
            _context = context;
            _parser = parser;
            _logger = logger;
        }
    }

    public class Parser : IParser
    {
        private readonly DbContext _context;
        private readonly ILogger _logger;

        //Dependency context passed in is the same object within the scope. See [1]
        public Parser(DbContext context, ILogger logger)
        {
            _context = context;
            _logger = logger;
        }
    }

    public class Logger : ILogger
    {
        private readonly DbContext _context;

        //Dependency context passed in is the same object within the scope. See [1]
        public Logger(DbContext context)
        {
            _context = context;
        }
    }

    public interface IProcessor
    {
    }

    public interface IParser
    {
    }

    public interface ILogger
    {
    }
}

1 个答案:

答案 0 :(得分:1)

你需要看看范围界定;目前您没有指定范围,因此所有依赖关系都将是单例。 与DBContext lifestlye一起注册ILogger以及IParserIProcessorScoped。 E.G。

container.Register(Component.For<DBContext>()
    .ImplementedBy<DBContext>()
    .Lifestyle.Scoped);

然后,您需要解决依赖关系并在范围内使用它们。这通常会在基础架构中进行管理,但最简单的就是这样:

using(container.BeginScope()) 
{
    var processor = container.Resolve<IProcessor>();
    // use processor here.
}

现在,每个范围将创建一个新的DBContext,并在容器范围结束时进行处理。您不必担心初始化DBContext或将其传递给Resolve方法。