Autofac解析不在表示层中的对象

问题描述 投票:0回答:1

我正在使用Autofac来解析对象,我不希望每次都在类中使用构造函数注入。因此我定义了一个基类,但属性注入并没有解决我的问题。每次当我试图从派生类到我的基类上的这个属性时,它都是null。

举个例子

public abstract class Service
{
    public static IUnitOfWork _unitOfWork;
}

我有一个名为service的基类。

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.Register(c => Service.UnitOfWork = c.Resolve<IUnitOfWork>());

我的注册就像在上面。

我有两个问题,

  1. 可以将UnitOfWork属性定义为static是危险的吗?
  2. 如何轻松解决IUnitOfWork?
c# asp.net-mvc inversion-of-control autofac ioc-container
1个回答
0
投票

你绝对应该再次考虑构造函数注入模式并遵循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的派生类型。至于你的第一个问题,公共静态字段是全局变量,以这种方式存储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();
    }
} 

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.