使用 AutoFac 属性 注入最小起订量

Using AutoFac Property Injection with Moq

考虑以下 class:

public class ViewModelBase
{
    public IService Service { get; protected set; }
}

和这个 class 的测试:

using var mock = AutoMock.GetLoose();
var viewModelBase = mock.Create<ViewModelBase>();
Assert.NotNull(viewModelBase.Service);

在我的正常应用程序中,我使用 Autofac.Core.NonPublicProperty 的 属性 注入功能将 IService 依赖项自动装配到 ViewModelBase:

containerBuilder.RegisterType(typeof(ViewModelBase)).AutoWireNonPublicProperties();

在测试中,我使用 Autofac.Extras.Moq 集成包来自动模拟 ViewModelBase 的依赖项。但是,据我所知,Autofac.Extras.Moq 仅支持构造函数注入。这会导致测试失败,因为 Service 属性 未由 Moq 自动装配。

是否有任何优雅的方式来利用 AutoFac 的 属性 注入功能和 Moq?

only constructor injection is supported by Autofac.Extras.Moq

实际上你是对的,但是 AutoMock.GetLoose 有一个重载,你可以通过将 ContainerBuilder 的委托与所有常规autofac 特点:

public class AutoMock : IDisposable
{
    //...  
    public IContainer Container { get; }
    public static AutoMock GetLoose(Action<ContainerBuilder> beforeBuild);
    //...
}

在您的情况下,扩展 Autofac.Extras.Moq 不支持 PropertiesAutowired() 方法,因此我们可以构建一个 ContainerBuilder 并通过委托传递它:

Action<ContainerBuilder> containerBuilderAction = delegate(ContainerBuilder cb)
{
    cb.RegisterType<ServiceFoo>().As<IService>();
    cb.RegisterType<ViewModelBase>().PropertiesAutowired(); //The autofac will go to every single property and try to resolve it.
};

var mock = AutoMock.GetLoose(containerBuilderAction);
        
var viewModelBase = mock.Create<ViewModelBase>();            
Assert.IsNotNull(viewModelBase.Service);

使用 IService 实现 class of ServiceFoo:

public class ServiceFoo : IService` { }