使用 Castle Windsor 在开始新范围时我需要一个对象的新实例

Using Castle Windsor I need a new instance of an object when starting a new scope

我正在尝试实现如下所示的对象构造,它会在使用范围内创建一个新的 DbContext,因此在离开使用范围时会被丢弃。因此,如下所示,我在两个单独的使用范围中创建了两个处理器对象。我想使用 Castle Windsor.

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

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

我在 之前问过一个类似的问题,该问题建议使用范围,但我无法让它按我想要的方式工作。请参阅下面的完整程序。

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

namespace IOCTesting
{
    class Program
    {
        static void Main(string[] args)
        {
            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>());

            container.Register(Component.For<DbContext>()
                .ImplementedBy<DbContext>()
                .LifeStyle
                .Scoped());

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

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

    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;

        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;

        public Parser(DbContext context, ILogger logger)
        {
            _context = context;
            _logger = logger;
        }
    }

    public class Logger : ILogger
    {
        private readonly DbContext _context;

        public Logger(DbContext context)
        {
            _context = context;
        }
    }

    public interface IProcessor
    {
    }

    public interface IParser
    {
    }

    public interface ILogger
    {
    }
}

在退出第一个 container.BeginScope() 时调用 DbContext 上的 Dispose 方法,但在第二次调用容器时。 BeginScope() 退出第二个作用域时 Dispose 方法不会被调用。

这意味着容器在第二个容器时为我提供了相同的处置 DbContext 实例。 BeginScope() 被调用。本质上,我需要 DbContentcontainer.BeginScope() 中是瞬态的,并且容器在每个新创建的范围上给我一个新的 DbContext 实例,以便在退出范围时始终将其处理掉。

希望这是有道理的。

IProcessorIParserILogger也需要注册为Scoped

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

对依赖于 DBContext 的所有组件执行此操作。

如果没有明确设置生活方式,则默认为单身。因此,第一次解析 IProcessor 时,实例化了单例,它的依赖项被解析,包括作用域 DBContext。在第一个作用域的末尾,DBContext 被释放并释放,但是单例 IProcessor 仍然有一个指向已释放 DBContext 的引用。当您在第二个作用域中解析 IProcessor 时,返回已实例化的单例,其中包含已处理的 DBContext.