代码之家  ›  专栏  ›  技术社区  ›  Artyom Sokolov

Apache Ignite.NET服务中的依赖注入

  •  2
  • Artyom Sokolov  · 技术社区  · 7 年前

    有一个简单的服务,它将在任何节点上运行:

    public class ClientConnectionService : IClientConnectionService, IService
    {
        private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
    
        [InstanceResource] private IIgnite Ignite { get; set; }
    
        public void Listen(string hostname, int port, uint username, string password,
            ClientConnectionListenerOptions options = ClientConnectionListenerOptions.All)
        {
            Logger.Debug("Listen");
        }
    
        public void Init(IServiceContext context)
        {
            Logger.Debug("Initialized");
        }
    
        public void Execute(IServiceContext context)
        {
            Logger.Debug("Executed");
        }
    
        public void Cancel(IServiceContext context)
        {
            Logger.Debug("Canceled");
        }
    }
    

    应用程序使用Castle Windsor作为控制容器的反转。

    我想注入自定义依赖项,这些依赖项不会被序列化并通过连线传输。

    有什么办法可以实现吗?

    N、 B.在Java版本中,有 @SpringResource [InstanceResource] 属性。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Artyom Sokolov    7 年前

    这就是我的结局:

    1. 在描述了所有接口和契约的共享项目中,我介绍了IContainer
        public interface IContainer
        {
            T Resolve<T>();
        }
    
    1. 在负责Apache Ignite.NET集成的项目中,我实现了简单的Apache Ignite.NET插件
        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)
            {
                // No-op
            }
    
            public int? PluginConfigurationClosureFactoryId { get; } = null; // No Java part
        }
    
        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)
            {
    
            }
        }
    
    1. 在负责连接所有组件的主项目中,我实现了先前定义的IContainer,并在Castle Windsor中注册了它:
        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>()
                );
            }
        }
    
        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()}
                        }))
                );
            }
        }
    
    1. 最后,在应用程序的主要方法中:
        // Build Windsor container
        using (var container = new WindsorContainer())
        {
            // Install DI abstraction layer
            container.Install(new DependencyInjectionInstaller());
    
            // Install cluster abstraction layer
            container.Install(new IgniteInstaller());
    
            // Attach DI container to cluster plugin
            container
                .Resolve<IIgnite>()
                .GetPlugin<DependencyInjectionPlugin>("DependencyInjection")
                .Container = container.Resolve<IContainer>();
    
            // Wait
            Done.Wait();
        }
    

    就这样。从现在起,我可以访问Apache Ignite.NET分布式服务中的IContainer实现,如下所示:

        var plugin = Ignite.GetPlugin<DependencyInjectionPlugin>("DependencyInjection");
        var whatever = plugin.Resolve<IWhatever>();
    
    推荐文章