Inversion of Control (IoC), Dependency Inversion Principle (DIP) và Dependency Injection (DI), CAB&SCSF cũng chỉ viết tới Part 03: Dependency Injection
Gần đây coi lại và thấy lần này nên note kỹ. Nói chung đầu tiên là lược dịch từ những tutorials trên NET bắt đầu từ series trên BitterCoder (đã rất lâu rồi từ tận 2007). Có thể đọc thêm hướng dẫn từ project chính thức trên Github castleproject/Windsor.
Gần đây có nhiều lựa chọn IoC container cho .NET gồm có Autofac, StructureMap, Unity. Một vài container có vẻ dần chiếm được nhiều quan tâm hơn như Autofac với simple API, dễ sử dụng và performance tốt. Tuy nhiên Windsor nói chung vẫn đáp ứng được yêu cầu đặt ra với nhiều module (facilities) từ logging, NHibernate, ASP.NET MVC ...
Configuration parameters
Part đầu tiên là configuration parameters. Windsor cho phép cấu hình component với parameters run-time. Mặc dù có thể configuration với .NET qua app.config bình thường nhưng sử dụng với Windsor khá là đơn giản và tiện dụng.
Giả sử có một class là Tax, mặc định tax rate là 10%. Có thể config rate thông qua app.config.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Tax { private decimal rate = 0.10m; public decimal Rate { set { rate = value; } get { return rate; } } public decimal Calculate( decimal gross) { return Math.Round(rate * gross, 2); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | using Castle.Windsor; using Castle.Windsor.Configuration.Interpreters; using System; namespace ConsoleApp { public class Tax { private decimal rate = 0.10m; public decimal Rate { set { rate = value; } get { return rate; } } public decimal Calculate( decimal gross) { return Math.Round(rate * gross, 2); } } class Program { static void Main( string [] args) { WindsorContainer container = new WindsorContainer( new XmlInterpreter()); // Resolve Tax calculator = container.Resolve<Tax>(); decimal gross = 100; decimal tax = calculator.Calculate(gross); Console.WriteLine( "Gross: {0}, Tax: {1}" , gross, tax); Console.ReadLine(); } } } |
Thực hiện Build và Run sẽ ra báo lỗi không có config section 'castle'.
1 2 3 4 5 6 7 8 9 10 11 | <? xml version = "1.0" encoding = "utf-8" ?> < configuration > < configSections > < section name = "castle" type = "Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </ configSections > < castle > </ castle > < startup > < supportedRuntime version = "v4.0" sku = ".NETFramework,Version=v4.6.2" /> </ startup > </ configuration > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <? xml version = "1.0" encoding = "utf-8" ?> < configuration > < configSections > < section name = "castle" type = "Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </ configSections > < castle > < components > < component id = "tax" type = "ConsoleApp.Tax, ConsoleApp" > </ component > </ components > </ castle > < startup > < supportedRuntime version = "v4.0" sku = ".NETFramework,Version=v4.6.2" /> </ startup > </ configuration > |
Thực hiện setup rate bằng parameters như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <? xml version = "1.0" encoding = "utf-8" ?> < configuration > < configSections > < section name = "castle" type = "Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </ configSections > < castle > < components > < component id = "tax" type = "ConsoleApp.Tax, ConsoleApp" > < parameters > < rate >0.25</ rate > </ parameters > </ component > </ components > </ castle > < startup > < supportedRuntime version = "v4.0" sku = ".NETFramework,Version=v4.6.2" /> </ startup > </ configuration > |
Với id="tax" có thể dùng để resolve component khác nhau, ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <? xml version = "1.0" encoding = "utf-8" ?> < configuration > < configSections > < section name = "castle" type = "Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </ configSections > < castle > < components > < component id = "tax1" type = "ConsoleApp.Tax, ConsoleApp" > < parameters > < rate >0.25</ rate > </ parameters > </ component > < component id = "tax2" type = "ConsoleApp.Tax, ConsoleApp" > < parameters > < rate >0.05</ rate > </ parameters > </ component > </ components > </ castle > < startup > < supportedRuntime version = "v4.0" sku = ".NETFramework,Version=v4.6.2" /> </ startup > </ configuration > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | WindsorContainer container = new WindsorContainer( new XmlInterpreter()); decimal gross = 100; // Resolve tax #1 Tax calculator1 = container.Resolve<Tax>( "tax1" ); decimal tax1 = calculator1.Calculate(gross); Console.WriteLine( "Gross: {0}, Tax: {1}" , gross, tax1); // Resolve tax #2 Tax calculator2 = container.Resolve<Tax>( "tax2" ); decimal tax2 = calculator2.Calculate(gross); Console.WriteLine( "Gross: {0}, Tax: {1}" , gross, tax2); Console.ReadLine(); |
No comments:
Post a Comment