2014年11月13日 星期四

認識依賴反轉


一、認識IOCDI

程式為了保持隔離性和彈性,所以使用介面,與相依的物件隔離  


範例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導入專案中,將需要產生更多介面類別,雖然非常彈性的注入類別,但也增加複雜度,選擇最合適專案方式,才是上策, 如有錯誤的地方,歡迎多多指導。




沒有留言:

張貼留言