一、認識IOC、DI
程式為了保持隔離性和彈性,所以使用介面,與相依的物件隔離
範例1: Robot 直接相依於Car
範例2: 原本直接相依的程式,增加介面ICar, 並沒直接相依於
僅管有彈性的使用繼承ICar類別, 但如果有許多地方要切換其他類別,反而會很困擾,所以有工具直接設定好注入的類別,此後只需把類別名稱修改之後,程式也自動切換注入的類別,同時保有彈性和便利性。
Public
class runRobot
{
Public void run(ICar car)
{
Car.Run();
}
}
|
二、安裝AutoFac
三、宣告類別、介面
class fish:IAnimal
{
public void behavior()
{
try
{
Console.Write("i am a happy fish");
Console.ReadLine();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
class bird:IAnimal
{
public void behavior()
{
try
{
Console.Write("i am a happy bird");
Console.ReadLine();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
interface IAnimal
{
void behavior();
}
|
四、註冊AutoFact ,並注入對應類別
1.
SingleInstance 單次註冊
後續的注入類別仍會依照註冊的類別,自動實作此類別,直到此元件的生命周期結束為止。
static void Main(string[] args)
{
try
{
var builder = new ContainerBuilder();//建立容器
builder.Register(c
=> new fish()).SingleInstance(); //單次註冊
var a = builder.Build().Resolve<fish>(); //注入fish 類別
//如果將fish 切換成 bird,不用更改任何程式,自動切換成bird 的類別
start(a);
Console.ReadLine();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
static void start(IAnimal animalObj)
{
animalObj.behavior();
Console.ReadLine();
}
|
2.
BeginLifetimeScope 生命週期
注入類別只會在生命週期範圍內生效,完成生命週期後,立刻把將記憶體釋放掉
builder.RegisterType<fish>().As<IAnimal>(); //註冊類型
var Container = builder.Build();
using (var scope
= Container.BeginLifetimeScope()) //建立生命週期
{
var animal = scope.Resolve<IAnimal>(); //注入類別 fish
start(animal);
}
|
我所注入的類別是fish, 所以呈現出"i am a happy fish",如果切換成bird類別,只需註冊 register 相對應的介面和類別,可輕易切換類別,是不是超級簡單呢。
五、結論
如果要將AutoFac導入專案中,將需要產生更多介面類別,雖然非常彈性的注入類別,但也增加複雜度,選擇最合適專案方式,才是上策, 如有錯誤的地方,歡迎多多指導。
沒有留言:
張貼留言