Looks good to me in general.
But we should add IDependencyResolver {get;set} to IgniteConfiguration
class instead of changing IIgnite interface.
We need the resolver at startup before IIgnite instance is created, to
resolve user-defined cache stores and so on.
And we should make sure to add tests for all kinds of user-defined classes
that are instantiated by Ignite:
Compute jobs, actions, services, cache stores, ICacheEntryFilter,
ICacheEntryProcessor, etc.
Thanks,
Pavel
On Thu, Sep 13, 2018 at 4:03 PM Artyom Sokolov <[email protected]> wrote:
> Hello,
>
> I propose the following.
>
> *Development*
>
> 1. Define *IDependencyResolver* in *Apache.Ignite.Core* under
> *DependencyInjection* folder that contains at least 2 methods:
>
> *T Resolve<T>(object arguments = null);*
> *object Resolve(Type type, object arguments = null);*
>
> 2. Create *InjectResolvableAttribute* in Apache.Ignite.Core under
> *DependencyInjection* folder marked with
> *[AttributeUsage(AttributeTargets.Field
> | AttributeTargets.Property)]*
> 3. Create internal static class *DependencyInjector* with at least one
> internal static method that will inject required dependencies in service
> implementations like this one (exception checking is omitted currently and
> has to be added)
>
> *namespace Apache.Ignite.Core.DependencyInjection*
> *{*
> * using System.Linq;*
> * using System.Reflection;*
> * using Apache.Ignite.Core.Services;*
>
> * internal static class DependencyInjector*
> * {*
> * internal static void Inject(IService svc, IIgnite ignite)*
> * {*
> * var dependencyResolver = ignite.GetDependencyResolver();*
>
> * if (dependencyResolver == null)*
> * {*
> * return;*
> * }*
>
> * foreach (var property in svc.GetType()*
> * .GetProperties(BindingFlags.Public |
> BindingFlags.NonPublic | BindingFlags.Instance))*
> * {*
> * if
> (!property.GetCustomAttributes(typeof(InjectResolvableAttribute),
> true).Any())*
> * {*
> * continue;*
> * }*
>
> * if (!property.CanWrite)*
> * {*
> * continue;*
> * }*
>
> * var resolvedDependency =
> dependencyResolver.Resolve(property.PropertyType);*
> * property.SetValue(svc, resolvedDependency, null);*
> * }*
>
> * foreach (var field in svc.GetType()*
> * .GetFields(BindingFlags.Public | BindingFlags.NonPublic |
> BindingFlags.Instance))*
> * {*
> * if
> (!field.GetCustomAttributes(typeof(InjectResolvableAttribute),
> true).Any())*
> * {*
> * continue;*
> * }*
>
> * var resolvedDependency =
> dependencyResolver.Resolve(field.FieldType);*
>
> * field.SetValue(svc, resolvedDependency);*
> * }*
> * }*
> * }*
> *}*
>
> 4. Add* DependencyInjector.Inject(svc, _ignite);* call to
> *UnmanagedCallbacks.cs* right after *ResourceProcessor.Inject(svc,
> _ignite)*
> .
> 5. Add 2 methods to *Ignite* class and it's interface *IIgnite*:
>
> *public IDependencyResolver GetDependencyResolver();*
> *public IIgnite SetDependencyResolver(IDependencyResolver
> dependencyResolver);*
>
> 6. Create *Apache.Ignite.DependencyInjection.CastleWindsor* project and
> implement *IDependencyResolver* with *CastleWindsorDependencyResolver*
> class.
>
> *namespace Apache.Ignite.DependencyInjection.CastleWindsor*
> *{*
> * using System;*
> * using Castle.MicroKernel;*
> * using IDependencyResolver =
> Core.DependencyInjection.IDependencyResolver;*
>
> * public class CastleWindsorDependencyResolver : IDependencyResolver*
> * {*
> * private IKernel Kernel { get; set; }*
>
> * public CastleWindsorDependencyResolver(IKernel kernel)*
> * {*
> * Kernel = kernel;*
> * }*
>
> * public T Resolve<T>(object arguments = null)*
> * {*
> * return arguments == null ? Kernel.Resolve<T>() :
> Kernel.Resolve<T>(arguments);*
> * }*
>
> * public object Resolve(Type type, object arguments = null)*
> * {*
> * return arguments == null ? Kernel.Resolve(type) :
> Kernel.Resolve(type, arguments);*
> * }*
> * }*
> *}*
>
> 7. Create extension like this one
>
> namespace Apache.Ignite.DependencyInjection.CastleWindsor
> {
> using Apache.Ignite.Core;
> using Castle.MicroKernel;
>
> public static class IgniteExtensions
> {
> public static IIgnite UseCastleWindsorResolver(this IIgnite ignite,
> IKernel kernel)
> {
> return ignite.SetDependencyResolver(new
> CastleWindsorDependencyResolver(kernel));
> }
> }
> }
>
> 8. Write test.
>
>
> *Usage*
>
> var grid = Ignition.Start();
>
> using (var container = new WindsorContainer())
> {
>
> container.Register(Component.For<IInjectableBar>().ImplementedBy<InjectableBar>());
>
> grid.UseCastleWindsorResolver(container.Kernel);
> grid.GetServices().DeployClusterSingleton("FooService", new FooService());
> }
>
>
> What do you think?
>
> Cheers,
> Artyom.
>
> On Mon, Sep 10, 2018 at 5:23 PM Pavel Tupitsyn <[email protected]>
> wrote:
>
> > Hi Artyom,
> >
> > Ticket already exists: https://issues.apache.org/jira/browse/IGNITE-9299
> > Feel free to grab it.
> >
> > But before diving deep into coding, can you please provide a short
> overview
> > of the proposed implementation?
> > Either on dev list or in JIRA ticket directly.
> >
> > Thanks,
> > Pavel
> >
> > On Mon, Sep 10, 2018 at 11:29 AM Alexey Goncharuk <
> > [email protected]> wrote:
> >
> > > Hello Artyom,
> > >
> > > Welcome to the Apache Ignite community! I've added you to the list of
> > > contributors, you should now be able to assign tickets to yourself.
> > >
> > > Get familiar with Apache Ignite development process described here:
> > > https://cwiki.apache.org/confluence/display/IGNITE/Development+Process
> > >
> > > Instructions on how to contribute can be found here:
> > > https://cwiki.apache.org/confluence/display/IGNITE/How+to+Contribute
> > >
> > > Project setup in Intellij IDEA:
> > > https://cwiki.apache.org/confluence/display/IGNITE/Project+Setup
> > >
> > > --AG
> > >
> > > вс, 9 сент. 2018 г. в 15:20, Artyom Sokolov <[email protected]>:
> > >
> > > > Hello,
> > > >
> > > > I would like to start implementing IoC/DI support (Autofac, Castle
> > > Windsor,
> > > > etc.) in Apache Ignite.NET.
> > > >
> > > > Please add me as a contributor in JIRA, so I could create ticket and
> > > start
> > > > working on this.
> > > >
> > > > My JIRA username is applicazza.
> > > >
> > > > Cheers,
> > > > Artyom.
> > > >
> > >
> >
>