在开发使用流行的
Castle Windsor库
注入依赖项并将
Apache Ignite.NET作为打开云计算之门的“关键”的各种应用程序时,我遇到了一点不便:我无法将依赖项注入到已启动的服务中通过所谓的服务网格。
发生这种情况的原因很普遍。 Apache Ignite.NET对服务进行序列化,然后将其发送到可用服务器之一,然后在其中进行反序列化和启动。 由于此过程绝不了解温莎城堡,因此我们得到了我们所得到的。
为了解决此问题,我们需要为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"); } }