使用 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()
被调用。本质上,我需要 DbContent
在 container.BeginScope()
中是瞬态的,并且容器在每个新创建的范围上给我一个新的 DbContext
实例,以便在退出范围时始终将其处理掉。
希望这是有道理的。
IProcessor
、IParser
、ILogger
也需要注册为Scoped
。
container.Register(Component.For<IProcessor>()
.ImplementedBy<Processor>()
.LifeStyle.Scoped());
对依赖于 DBContext
的所有组件执行此操作。
如果没有明确设置生活方式,则默认为单身。因此,第一次解析 IProcessor
时,实例化了单例,它的依赖项被解析,包括作用域 DBContext
。在第一个作用域的末尾,DBContext
被释放并释放,但是单例 IProcessor
仍然有一个指向已释放 DBContext
的引用。当您在第二个作用域中解析 IProcessor
时,返回已实例化的单例,其中包含已处理的 DBContext
.
我正在尝试实现如下所示的对象构造,它会在使用范围内创建一个新的 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()
被调用。本质上,我需要 DbContent
在 container.BeginScope()
中是瞬态的,并且容器在每个新创建的范围上给我一个新的 DbContext
实例,以便在退出范围时始终将其处理掉。
希望这是有道理的。
IProcessor
、IParser
、ILogger
也需要注册为Scoped
。
container.Register(Component.For<IProcessor>()
.ImplementedBy<Processor>()
.LifeStyle.Scoped());
对依赖于 DBContext
的所有组件执行此操作。
如果没有明确设置生活方式,则默认为单身。因此,第一次解析 IProcessor
时,实例化了单例,它的依赖项被解析,包括作用域 DBContext
。在第一个作用域的末尾,DBContext
被释放并释放,但是单例 IProcessor
仍然有一个指向已释放 DBContext
的引用。当您在第二个作用域中解析 IProcessor
时,返回已实例化的单例,其中包含已处理的 DBContext
.