عند تطوير العديد من التطبيقات التي تستخدم مكتبة
Castle Windsor الشهيرة
لحقن التبعيات و
Apache Ignite.NET باعتبارها "المفتاح" الذي يفتح الباب أمام الحوسبة السحابية ، واجهت إزعاجًا طفيفًا: لم يكن لدي أي طريقة لإدخال التبعية في الخدمة التي تم إطلاقها من خلال شبكة خدمة ما يسمى.
والسبب في حدوث ذلك أمر شائع جدًا. يقوم Apache Ignite.NET بتسلسل الخدمة ، وإرسالها إلى أحد الخوادم المتاحة ، حيث يتم إلغاء تسلسلها وإطلاقها. نظرًا لأن هذه العملية ليست لها أي فكرة عن Castle Windsor ، فإننا نحصل على ما نحصل عليه.
لحل هذه المشكلة ، نحتاج إلى إنشاء مكون إضافي لـ Apache Ignite.NET ، والذي سيتلقى حاوية مسؤولة عن تنفيذ التبعيات وتزويد الخدمة بفرصة الوصول إليها من أجل تلقي كائن.
بادئ ذي بدء ، سنقدم مستوى إضافيًا من التجريد للحاوية ، مما يوفر حقن التبعية ، بحيث يمكننا بسهولة في المستقبل تغيير تنفيذها إلى آخر:
public interface IContainer { T Resolve<T>(); }
public class DependencyInjectionContainer : IContainer { protected IKernel Kernel { get; set; } public DependencyInjectionContainer(IKernel kernel) { Kernel = kernel; } public T Resolve<T>() { return Kernel.Resolve<T>(); } }
public class DependencyInjectionInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component .For<IContainer>() .ImplementedBy<DependencyInjectionContainer>() ); } }
لإنشاء مكون إضافي ، نحتاج إلى إنشاء 3 فئات: الفئة المسؤولة عن تكوين المكون الإضافي ، وموفر المكون الإضافي ، والمكون الإضافي نفسه مباشرةً.
public class DependencyInjectionPlugin { public IContainer Container { get; set; } public T Resolve<T>() { return Container.Resolve<T>(); } }
[PluginProviderType(typeof(DependencyInjectionPluginProvider))] public class DependencyInjectionPluginConfiguration : IPluginConfiguration { public void WriteBinary(IBinaryRawWriter writer) {
public class DependencyInjectionPluginProvider : IPluginProvider<DependencyInjectionPluginConfiguration> { public string Name { get; } = "DependencyInjection"; public string Copyright { get; } = "MIT"; protected DependencyInjectionPlugin DependencyInjectionPlugin { get; set; } public T GetPlugin<T>() where T : class { return DependencyInjectionPlugin as T; } public void Start(IPluginContext<DependencyInjectionPluginConfiguration> context) { DependencyInjectionPlugin = new DependencyInjectionPlugin(); } public void Stop(bool cancel) { } public void OnIgniteStart() { } public void OnIgniteStop(bool cancel) { } }
عظيم ، يبقى تحميل البرنامج المساعد في Apache Ignite.NET.
public class IgniteInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component .For<IIgnite>() .UsingFactoryMethod(() => Ignition.Start(new IgniteConfiguration { PluginConfigurations = new[] {new DependencyInjectionPluginConfiguration()} })) ); } }
عندما يبدأ التطبيق ، نقوم ، كالمعتاد ، بتهيئة حاوية حقن التبعية ، لكننا الآن على استعداد لتمريرها إلى البرنامج المساعد الذي كتبناه للتو:
var Done = new ManualResetEventSlim(false);
تهانينا ، إذا قرأت حتى النهاية ، يمكنك الحصول على أي تبعية من الحاوية الخاصة بك داخل الخدمة. يبدو هذا:
public class ClientConnectionService : IClientConnectionService, IService { private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); [InstanceResource] private IIgnite Ignite { get; set; } public void Init(IServiceContext context) { Logger.Debug("Initialized"); } public void Execute(IServiceContext context) { var plugin = Ignite.GetPlugin<DependencyInjectionPlugin>("DependencyInjection"); var whatever = plugin.Resolve<IWhatever>(); whatever.DoSomething(); } public void Cancel(IServiceContext context) { Logger.Debug("Canceled"); } }