Autofac - 屬性注入


屬性注入不同於通過構造函數方式傳入參數. 這里是通過注入的方式, 在類創建完畢之后, 資源釋放之前, 給屬性賦值.

這里, 我重新弄一些類來演示這一篇吧.

public class ClassA
{
    private readonly ClassB b;

    public ClassA(ClassB b)
    {
        this.b = b;
    }

    public void Show()
    {
        Console.WriteLine("I am ClassA's instance !");
    }
}

public class ClassB
{
    public ClassA A { get; set; }

    public void Show()
    {
        Console.WriteLine("I am ClassB's instance !");
    }

}

public class ClassC
{
   public string Name { get; set; }
public ClassD D { get; set; } public void Show() { Console.WriteLine("I am ClassC's instance !" + Name); } } public class ClassD { public void Show() { Console.WriteLine("I am ClassD's instance !"); } }

1. 一般方法

var builder = new ContainerBuilder();

builder.Register(n => new ClassC { D = n.Resolve<ClassD>(), Name = "Sniper"  });
builder.RegisterType<ClassD>();

var container = builder.Build();

var c = container.Resolve<ClassC>();
c.Show();
c.D.Show();

這種方法, 不止可以注入屬性, 還可以給字段賦值

 

2. 反射的方式

var builder = new ContainerBuilder();

builder.RegisterType<ClassD>();
var s = builder.RegisterType<ClassC>().PropertiesAutowired();

var container = builder.Build();

var c = container.Resolve<ClassC>();
c.Show();
c.D.Show();

這里需要注意一點, 由於ClassC中有ClassD格式的屬性, 所以ClassD也必須要注冊一下. 為什么呢? 來看一下源碼

PropertiesAutowired()方法里面, 主要就是調用上圖中的方法. 會通過反射的方式獲取屬性, 然后也是通過Resolve的方式來獲取屬性的值.

注:

  仔細觀察ClassA和ClassB, 可以發現, 他們循環依賴了, 那么如果我要得到ClassB, 怎么辦? 嘗試下第一種方法, 你會發現, 我去, 報錯了.

  嘗試下第二種方法, 還是報錯. 那怎么辦呢? 

var builder = new ContainerBuilder();

builder.RegisterType<ClassB>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).SingleInstance();
builder.Register(n=>new ClassA(n.Resolve<ClassB>()));

var container = builder.Build();

var b = container.Resolve<ClassB>();
b.Show();
b.A.Show();

還是通過反射的方式, 只不過要注意一下, 傳入參數和SingleInstance, 不加, 都會報錯的.

 

3. 通過名稱

var builder = new ContainerBuilder();

var s = builder.RegisterType<ClassC>().WithProperty("D", new ClassD());

var container = builder.Build();

var c = container.Resolve<ClassC>();
c.Show();
c.D.Show();

通過屬性名稱, 直接new一個實例給他

 

4. OnActivating/OnActivated 方式

此方法的執行時機, 是構造函數創建結束之后, 資源釋放之前, 所以在此期間也可以實現

var builder = new ContainerBuilder();

builder.RegisterType<ClassC>().OnActivating(e => e.Instance.D = e.Context.Resolve<ClassD>());
builder.RegisterType<ClassD>();

var container = builder.Build();

var c = container.Resolve<ClassC>();
c.Show();
c.D.Show();

這里的 OnActivating 也可換成 OnActivated . 實現這里的場景, 是能得到一樣的結果的.

 參考:

   AutoFac使用方法總結

   Autofac 組件、服務、自動裝配 《第二篇》

   Autofac文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM