簡體   English   中英

Autofac 中的裝飾器和屬性注入

[英]Decorators and property injection in Autofac

我正在嘗試為這些使用屬性注入的服務注冊裝飾器。
當我添加containerBuilder.RegisterDecorator<ServiceDecorator, IService>()時,不再注入屬性。
我猜 Autofac 正試圖將其注入裝飾器而不是原始服務。

我寫了一些測試來展示這個問題。 有服務和裝飾:

public interface IService
{
    bool NestedServiceIsNotNull();
}

public interface INestedService { }

public class Service : IService
{
    public INestedService NestedService { get; set; }

    public bool NestedServiceIsNotNull()
    {
        return NestedService != null;
    }
}

public class NestedService : INestedService { }

public class ServiceDecorator : IService
{
    private readonly IService _original;

    public ServiceDecorator(IService original)
    {
        _original = original;
    }

    public bool NestedServiceIsNotNull()
    {
        return _original.NestedServiceIsNotNull();
    }
}

以及測試方法:

[TestMethod]
public void PropertyInjectedServiceShouldNotBeNull()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<NestedService>().As<INestedService>();
    builder.RegisterType<Service>().As<IService>().PropertiesAutowired();
    var container = builder.Build();
    var service = container.Resolve<IService>();

    Assert.IsTrue(service.NestedServiceIsNotNull());
}

[TestMethod]
public void PropertyInjectedServiceShouldNotBeNullEvenIfDecoratorRegistered()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<NestedService>().As<INestedService>();
    builder.RegisterType<Service>().As<IService>().PropertiesAutowired();
    // Here's the difference - decorating the service
    // causes the assertion to fail.
    builder.RegisterDecorator<ServiceDecorator, IService>();
    var container = builder.Build();
    var service = container.Resolve<IService>();

    Assert.IsTrue(service.NestedServiceIsNotNull());
}

第一個測試通過,但第二個因斷言而失敗。

這是正確的行為嗎?
我正在處理一個遺留項目,所以我不應該通過將依賴項移動到構造函數來更改現有代碼。
有沒有辦法解決這個問題?

看來...您發現了一個錯誤! 喲! 我已經代表你在這里提出了一個問題。

然而,一切並沒有丟失——你仍然可以按照你想要的方式使用裝飾器,你只需要使用舊的不太漂亮的 Autofac 裝飾器語法來完成它。

var builder = new ContainerBuilder();
builder.RegisterType<NestedService>().As<INestedService>();

// Decorating the service with the old syntax works.
builder.RegisterType<Service>().Named<IService>("service").PropertiesAutowired();
builder.RegisterDecorator<IService>((c, inner) => new ServiceDecorator(inner), fromKey: "service");

var container = builder.Build();
var service = container.Resolve<IService>();

Assert.True(service.NestedServiceIsNotNull());

這里有更多關於如何使用這種舊語法的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM