使用Windsor城堡,我在启动新范围时需要一个对象的新实例



我正在尝试实现对象构建,如下所示,在离开使用范围时,在使用中创建了新的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));
        }

我在温莎城堡(Castle Windsor)在使用示波器的暗示中传播内联依赖性之前就问了一个类似的问题,但我无法按照我想要的方式工作。请参阅下面的整个程序。

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()时,Dispose上的CC_4方法被调用,但在第二个调用容器上。BeginScope()退出第二个范围时未调用Dispose方法。

这意味着当第二个容器时,给我一个相同的DEVED DBCONTEXT实例。BeginScope()被调用。从本质上讲,我需要DbContentcontainer.BeginScope()内进行瞬态,并且容器在每个新创建的范围上给我一个新的DbContext实例,因此当示波器退出时始终处置。

希望这是有道理的。

IProcessorIParserILogger也需要注册为Scoped

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

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

如果没有明确设置生活方式,则默认值为单例。因此,您第一次解决IProcessor Singleton是实例化的,它的依赖项是解决的,包括示波器的DBContext。在第一个范围的末尾,DBContext已释放并处置,但是单核IProcessor仍然引用了该处置的DBContext。当您在第二个范围中解析IProcessor时,返回已经实例化的单例,其中包含已经处置的DBContext

最新更新