Castle Windsor 传播内联依赖项
Castle Windsor propagating inline dependencies
我正在尝试实现如下所示的对象构造,
using (var context = new DbContext())
{
var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
}
但使用温莎城堡。我正在使用内联依赖项,如下面的代码所示,但正如 Castle Windsor 文档所述 "Inline dependencies don't get propagated" 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
{
}
}
您需要查看范围;目前您没有指定范围,因此所有依赖项都是单例。
注册 DBContext
以及 ILogger
、IParser
和 IProcessor
,全部使用 Scoped
生命值。例如
container.Register(Component.For<DBContext>()
.ImplementedBy<DBContext>()
.Lifestyle.Scoped);
然后你需要解决你的依赖关系并在一个范围内使用它们。这通常会在基础架构中进行管理,但最简单的情况如下所示:
using(container.BeginScope())
{
var processor = container.Resolve<IProcessor>();
// use processor here.
}
现在将为每个作用域创建一个新的 DBContext
,并在容器作用域结束时释放。您不必担心初始化 DBContext
或将其传递给 Resolve
方法。
我正在尝试实现如下所示的对象构造,
using (var context = new DbContext())
{
var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
}
但使用温莎城堡。我正在使用内联依赖项,如下面的代码所示,但正如 Castle Windsor 文档所述 "Inline dependencies don't get propagated" 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
{
}
}
您需要查看范围;目前您没有指定范围,因此所有依赖项都是单例。
注册 DBContext
以及 ILogger
、IParser
和 IProcessor
,全部使用 Scoped
生命值。例如
container.Register(Component.For<DBContext>()
.ImplementedBy<DBContext>()
.Lifestyle.Scoped);
然后你需要解决你的依赖关系并在一个范围内使用它们。这通常会在基础架构中进行管理,但最简单的情况如下所示:
using(container.BeginScope())
{
var processor = container.Resolve<IProcessor>();
// use processor here.
}
现在将为每个作用域创建一个新的 DBContext
,并在容器作用域结束时释放。您不必担心初始化 DBContext
或将其传递给 Resolve
方法。