Castle Windsor یکی از IoC Container های رایگان و متن باز (Open Source) دات نت می باشد. در این مقاله به بررسی نحوه ی تزریق وابستگی ها (Dependency Injection) در قالب کلاس های Lazy با استفاده از کتابخانه ی Castle Windsor میپردازیم.
در صورتی که با مفاهیم Dependency Injection و IoC Container آشنایی ندارید، می توانید به مطالعه ی این مقاله از آقای Martin Fowler بپردازید. همچنین جهت آشنایی با مفهوم Lazy Initialization و کلاس های Lazy در دات نت می توانید از این پست استفاده کنید.
کد زیر را در نظر بگیرید :
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 |
public interface IRegistrationService { void Register(UserViewModel user); } public class RegistrationService : IRegistrationService { private INotificationService notificationService; public RegistrationService(INotificationService notificationService) { this.notificationService = notificationService; } public void Register(UserViewModel user) { var isRegisterSuccess = false; . . . if (isRegisterSuccess) { notificationService.Notify(user); } } } |
کلاس Notification که از طریق Constructor به کلاس Registration تزریق شده است، تنها در صورتی استفاده می شود که ثبت نام کاربر با موفقیت انجام گیرد. در عین حال این کلاس با هر بار ساخته شدن کلاس Registration، ساخته شده و حافظه میگیرد (در صورتی که فرض کنیم این سرویس ها Singleton تعریف نشده اند). به نحوه ی Config این کلاس ها در Castle Windsor دقت کنید :
1 2 3 4 5 6 7 8 9 |
var container = new WindsorContainer(); container.Register(Component.For<IRegistrationService>() .ImplementedBy<RegistrationService>() .LifestylePerWebRequest()); container.Register(Component.For<INotificationService>() .ImplementedBy<NotificationService>() .LifestylePerWebRequest()); |
1 2 3 4 5 6 7 8 9 10 11 |
public class RegistrationService : IRegistrationService { private Lazy<INotificationService> notificationService; public RegistrationService(Lazy<INotificationService> notificationService) { this.notificationService = notificationService; } . . . } |
در صورتی که تغییر فوق را بر روی کد اعمال کنید، با خطا مواجه خواهد شد زیرا Castle Windsor کلاس NotificationService را شناخته اما کلاس Lazy آن را نمیشناسد. برای حل این مشکل کلاسی با نام LazyOfTComponentLoader در Castle Windsor 3 اضافه شده است و تنها نیاز است تا آن را در Kernel اضافه کنید :
1 2 3 4 5 6 7 |
var container = new WindsorContainer(); container.Kernel.Register(Component.For<ILazyComponentLoader>() .ImplementedBy<LazyOfTComponentLoader>()); . . . |
نکته مهم : قابلیت فوق در صورتی که Lifestyle کلاس از نوع Scoped و یا Bound باشد (در زمان نوشته شدن این مقاله، یعنی نسخه ی ۳٫۳ Castle Windsor) قابل استفاده نخواهد بود.
سلام
اینiocبه جز وب سایت خودش pdf معتبری هم در موردش هست؟؟
سلام
بنده PDF اختصاصا در مورد Castle Windsor ندیدم، چون داکیومنت هاش واقعا کامل هست و نیازی به مطالعه ی کتاب نیست. اما در کتاب Dependency Injection in .NET نوشته اقای Mark Seeman یک بخش در مورد این ابزار توضیح داده شده است.