NInject IBindingGenerator и ToProvider

Я создал этот код:

public class AddonsModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        this.Bind(b => b.FromAssembliesMatching("*")
            .SelectAllClasses()
            .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
            .BindWith(new AddonBindingGenerator())
        );
    }

    private class AddonBindingGenerator : IBindingGenerator
    {

        public System.Collections.Generic.IEnumerable<Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(System.Type type, Ninject.Syntax.IBindingRoot bindingRoot)
        {
            if (type.IsInterface || type.IsAbstract)
                yield break;

            yield return bindingRoot.Bind(type).ToProvider(typeof(UIExtensibility.AbstractAddon));
        }
    }

    private class AddonProvider : IProvider<UIExtensibility.AbstractAddon>
    {

        public object Create(IContext context)
        {
            return null;
        }

        public Type Type
        {
            get { throw new NotImplementedException(); }
        }
    }
}

AddonProvider, кажется, следует избегать. Это никогда не выполняется.

Когда я выполняю:kernel.GetAll<UIExtensibility.AbstractAddon>(), AddonProvider.Create метод никогда не выполняется.

Не могли бы вы сказать мне, что не так? Я очень ценю вашу помощь.

Спасибо за все.

3 ответа

AddOnProvider наследуется от IProvider<T> вместо UIExtensibility.AbstractAddon,

также у вас могут быть проблемы, связанные с закрытыми внутренними классами. делать AddOnProvider публичный класс высшего уровня.

Вы связываете определенный тип, который наследуется от typeof(UIExtensibility.AbstractAddon) к провайдеру. Например, может быть class Foo : UIExtensibility.AbstractAddon, Теперь ваше обязательное соглашение переводится так:

Bind<Foo>().ToProvider<AddonProvider>();

Сейчас, kernel.GetAll<UIExtensibility.AbstractAddon>() однако ищет привязки, сделанные как:

Bind<UIExtensibility.AbstractAddon>().To...

Почини это

Так что вам нужно изменить строку

bindingRoot.Bind(type).ToProvider(new AddonProvider());

чтобы:

bindingRoot.Bind(typeof(UIExtensibility.AbstractAddon)).ToProvider<AddonProvider>();

более того

  • ты линия object f = bindingRoot.Bind(type).ToProvider(new AddonProvider()); никогда не возвращает привязку (object f).
  • делает UIExtensibility.AbstractAddon воплощать в жизнь IProvider?

Спасибо за ваш ответ и комментарии.

Я считаю, что проблема в том, что я не совсем понимаю, как работает этот "общий" процесс связывания.

Я попытаюсь написать процесс обработки моих мозговых шагов:

  1. Мне нужно связать каждый AbstractAddon реализация внутри папки сборок аддонов. Итак, я думаю, что этот код правильный, но я совсем не уверен.

    this.Bind(b => b.FromAssembliesMatching("*")
        .SelectAllClasses()
        .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
        .BindWith(new AddonBindingGenerator())
    );
    
  2. мой AbstractAddon как:

    public abstract class AbstractAddon : IAddon
    {
    
        private object configuration;
    
        public AbstractAddon(object configuration)
        {
            this.configuration = configuration;
        }
    
        // IAddon interface
    
        public abstract string PluginId { get; }
    
        public abstract string PluginVersion { get; }
    
        public abstract string getCaption(string key);
    
        public abstract Type getConfigurationPanelType();
    
        public abstract System.Windows.Forms.UserControl createConfigurationPanel();
    
    }
    
  3. Я думаю, мне нужно:

    foreach implementation of `AbstractAddon` found out,
        I need to "inject" a configuration object ->
            So, I guess I need to set a provider and provide this configuration object.
    

Это было бы моим основным способом мышления для решения этой проблемы.

Я немного изменил свой первый подход. Вместо того, чтобы использовать класс IBindingGenerator, я использовал следующее:

    public class AddonsModule : Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
            this.Bind(b => b.FromAssembliesMatching("*")
                .SelectAllClasses()
                .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
                .BindAllBaseClasses()
                .Configure(c => c.InSingletonScope())
            );

            this.Bind<object>().ToProvider<ConfigurationProvider>()
                .WhenTargetHas<UIExtensibility.ConfigurationAttribute>();
        }

Итак, мой ConfigurationProvider это:

private class ConfigurationProvider : IProvider<object>
{

    public object Create(IContext context)
    {
        return "configuration settings";
    }
}

И теперь мой конструктор AbstractAddon содержит параметр, аннотированный с помощью ConfigurationAttribute:

public AbstractAddon([Configuration]object configuration)
{
    this.configuration = configuration;
}

Проблема сейчас в том, что NInject, похоже, игнорирует провайдера объекта конфигурации. NInject генерирует объект дампа, однако не выполняет ConfigurationProvider.Create метод...

Что я делаю не так, сейчас? Этот подход действительно лучше, чем предыдущий? Спасибо за все.

Другие вопросы по тегам