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>());

我的注册就像上面一样。

我有两个问题,

  1. 将 UnitOfWork 属性 定义为静态会很危险吗?
  2. 如何轻松解决 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();
} 

这里 ServiceImplService 的派生类型。至于你的第一个问题,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();
    }
} 

希望对您有所帮助。