Ninject - перехватить разрешение множественного связывания - PullRequest
2 голосов
/ 12 марта 2012

Есть ли способ заставить Ninject вызывать функцию, когда у нее проблемы с разрешением множественного связывания?

В принципе, я хотел бы иметь это:

static void Main(string[] args)
{
    StandardKernel k = new StandardKernel();
    k.Bind<IProvideConn>().To<probe1>(); // these bindings are actually done by assembly scanner, I don't know how many types are available
    k.Bind<IProvideConn>().To<probe2>();
    k.Bind<plugin1>().ToSelf();

    k.Get<plugin1>(); // Currently throws a "multiple bindings registered" exception
                      //but I would like it to call solveMyIssues.sortThingsOut
}

public class solveMyIssues
{
    public IBinding sortThingsOut(IEnumerable<IBinding> availableBindingsForThisResolve)
    {
        int i = AskChoiceFromUser(availableBindingsForThisResolve);
        return availableBindingsForThisResolve[i];
    }
}

interface IProvideConn0
{
    void goCrazy();
}

public class plugin1
{
    public void talkWithUser(IProvideConn0 pc)
    {
        pc.goCrazy();
    }
}

public class probe1 : IProvideConn0
{
    public void goCrazy() {}
}

public class probe2 : IProvideConn0
{
    public void goCrazy() {}
}

Больше контекста:
Я использую Ninject в плагине, как архитектура Плагины могут использовать один или несколько типов провайдеров соединений (каждый тип провайдера соединений имеет интерфейс, который наследуется от IMotherConnProv).
В настоящее время я использую расширение XML для сопоставления каждого IProvideConnX с реализацией (каждый IProvideConnX может иметь несколько реализаций), но пользователям довольно утомительно редактировать файлы XML, когда они хотят изменить типы подключения.

Я сделал небольшое приложение, которое помогает им изменять XML-файл с помощью блестящих кнопок и всего остального, но я чувствую, что должен быть более динамичный способ сделать это (Ninject собирается освободиться от XML, верно?).
Поэтому я хотел бы использовать сканер сборки, чтобы обнаружить все возможные варианты и как-то сообщить Ninject во время выполнения, какую привязку выбрать (в зависимости от выбора пользователя).

Есть идеи? (Я посмотрел на это решение , но не могу понять, как адаптировать его к неопределенному количеству интерфейсов и реализаций)

1 Ответ

2 голосов
/ 12 марта 2012

Нет, ты не можешь.Но вы можете настроить привязки так, чтобы этого не произошло:

kernel.Bind(
    x => x.FromThisAssembly()
          .SelectAllClasses().InheritedFrom<IProvideConn0>()
          .BindToAllInterfaces()
          .Configure((binding, componentType) => b.When(r => kernel.Get<IConfiguration>().ConnectionType == componentType.Name)));
kernel.Bind(
    x => x.FromThisAssembly()
          .SelectAllClasses().InheritedFrom<IConnectionType>()
          .BindToAllInterfaces();

public class Configuration : IConfiguration
{
    public Configuration(IEnumerable<IConnectionType> connectionTypes) { ... }

    public string ConnectionType
    {
        get 
        {
            return this.UserWhichConnectionDoYouWant(connectionTypes);
        }
    }
}

и добавить IConnectionType для каждого соединения, указав необходимую информацию, чтобы пользователь мог выбрать ее.

См. https://github.com/ninject/ninject.extensions.conventions/wiki/What-is-configuration-by-conventions

...