Инъекционное связывание на основе свойства объекта? Конвенция или контекстная привязка?

У меня есть интерфейс:

public interface IInterface
{
string Get(obj o);
}

и у меня есть 2 класса:

public class C1 : IInterface
{
string Get(obj o);
}

public class C2 : IInterface
{
string Get(obj o);
}

Я хотел бы отправить в o, а затем дать Ninject определить, на каком интерфейсе он основан на свойстве o. Obj что-то вроде:

public class obj
{
    public string Name {get;set;}
    public int Id {get;set;}
}

Я хотел бы что-то вроде:

Bind<IInterface>().To<C1>.When(obj.Name == "C1");
Bind<IInterface>().To<C2>.When(obj.Name == "C2");

но я не работал с Ninject раньше. Есть идеи?

1 ответ

Решение

Я был несколько либерален с интерпретацией вашего вопроса, потому что я думаю, что вы пропустили некоторые "мыслительные шаги" и необходимую информацию.

Тем не менее, я рекомендую делать это так:

public interface INamed
{
    string Name { get; }
}

public interface IFactory
{
    IInterface Create(INamed obj);
}

public class Factory : IFactory
{
    private readonly IResolutionRoot resolutionRoot;

    public Factory(IResolutionRoot resolutionRoot)
    {
        this.resolutionRoot = resolutionRoot;
    }

    public IInterface Create(INamed obj) 
    {
        return this.resolutionRoot.Get<IInterface>(obj.Name);
    }
}

Альтернатива: вы также можете использовать заводское расширение ninject. К сожалению, по умолчанию он не поддерживает именованные привязки, но вы можете настроить его, как описано здесь.

Однако, чтобы быть совершенно откровенным, я бы предпочел вручную внедрить фабрику, потому что это легче понять. Если бы я настраивал фабрику - что я и сделал - я бы рассмотрел добавление поддержки атрибутов (которые определяют, как обрабатывать параметр метода фабрики) вместо необходимости настраивать каждый из них. .ToFactory() привязка, как он будет интерпретировать параметры.

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