Autofac 解析不在表示层中的对象
Autofac Resolve an object which is not in Presentation Layer
我正在使用 Autofac 来解析对象,我不想在 classes 中每次都使用 构造函数注入。因此我定义了一个基础 class 但 属性 注入 没有解决我的问题。每次当我试图从派生 class 到达我的基础 class 上的这个 属性 时,它是空的。
举个例子
public abstract class Service
{
public static IUnitOfWork _unitOfWork;
}
我有一个名为 service 的基地 class。
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.Register(c => Service.UnitOfWork = c.Resolve<IUnitOfWork>());
我的注册就像上面一样。
我有两个问题,
- 将 UnitOfWork 属性 定义为静态会很危险吗?
- 如何轻松解决 IUnitOfWork?
你绝对应该再次考虑构造函数注入模式并听从 Mark 的建议。然而,为了让您的方法奏效,您可以这样做:
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<ServiceImpl>().As<Service>()
.OnActivated(e => Service.UnitOfWork = e.Context.Resolve<IUnitOfWork>());
var container = builder.Build();
var service = container.Resolve<Service>();
Console.WriteLine(Service.UnitOfWork);
Console.ReadKey();
}
这里 ServiceImpl
是 Service
的派生类型。至于你的第一个问题,public 静态字段是全局变量,以这种方式存储 UnitOfWork 根本不是一个好主意。此外, UnitOfWork 的整个想法与此相矛盾。至少创建 UnitOfWork
实例 属性 会更好,保护它分配多次然后在 ServiceImpl.Dispose
.
中显式处理它
UPD:例如 属性 注入方法的附加示例:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<ServiceImpl>().As<Service>()
.OnActivated(e => e.Instance.UnitOfWork = e.Context.Resolve<IUnitOfWork>());
var container = builder.Build();
var service = container.Resolve<Service>();
Console.WriteLine(service.IsUnitOfWorkInjected);
Console.ReadKey();
}
}
public abstract class Service : IDisposable
{
private IUnitOfWork _unitOfWork;
private static readonly object padlock = new object();
public IUnitOfWork UnitOfWork
{
protected get => _unitOfWork;
set
{
if (_unitOfWork == null)
{
lock (padlock)
{
if (_unitOfWork == null)
{
_unitOfWork = value;
}
}
}
}
}
public bool IsUnitOfWorkInjected => UnitOfWork != null;
public void Dispose()
{
_unitOfWork?.Dispose();
}
}
希望对您有所帮助。
我正在使用 Autofac 来解析对象,我不想在 classes 中每次都使用 构造函数注入。因此我定义了一个基础 class 但 属性 注入 没有解决我的问题。每次当我试图从派生 class 到达我的基础 class 上的这个 属性 时,它是空的。
举个例子
public abstract class Service
{
public static IUnitOfWork _unitOfWork;
}
我有一个名为 service 的基地 class。
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.Register(c => Service.UnitOfWork = c.Resolve<IUnitOfWork>());
我的注册就像上面一样。
我有两个问题,
- 将 UnitOfWork 属性 定义为静态会很危险吗?
- 如何轻松解决 IUnitOfWork?
你绝对应该再次考虑构造函数注入模式并听从 Mark 的建议。然而,为了让您的方法奏效,您可以这样做:
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<ServiceImpl>().As<Service>()
.OnActivated(e => Service.UnitOfWork = e.Context.Resolve<IUnitOfWork>());
var container = builder.Build();
var service = container.Resolve<Service>();
Console.WriteLine(Service.UnitOfWork);
Console.ReadKey();
}
这里 ServiceImpl
是 Service
的派生类型。至于你的第一个问题,public 静态字段是全局变量,以这种方式存储 UnitOfWork 根本不是一个好主意。此外, UnitOfWork 的整个想法与此相矛盾。至少创建 UnitOfWork
实例 属性 会更好,保护它分配多次然后在 ServiceImpl.Dispose
.
UPD:例如 属性 注入方法的附加示例:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<ServiceImpl>().As<Service>()
.OnActivated(e => e.Instance.UnitOfWork = e.Context.Resolve<IUnitOfWork>());
var container = builder.Build();
var service = container.Resolve<Service>();
Console.WriteLine(service.IsUnitOfWorkInjected);
Console.ReadKey();
}
}
public abstract class Service : IDisposable
{
private IUnitOfWork _unitOfWork;
private static readonly object padlock = new object();
public IUnitOfWork UnitOfWork
{
protected get => _unitOfWork;
set
{
if (_unitOfWork == null)
{
lock (padlock)
{
if (_unitOfWork == null)
{
_unitOfWork = value;
}
}
}
}
}
public bool IsUnitOfWorkInjected => UnitOfWork != null;
public void Dispose()
{
_unitOfWork?.Dispose();
}
}
希望对您有所帮助。