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 <unn...@gmail.com> 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 <ptupit...@apache.org>
> 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 <
> > alexey.goncha...@gmail.com> 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 <unn...@gmail.com>:
> > >
> > > > 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.
> > > >
> > >
> >
>

Reply via email to