Молчаливый неудачник - PullRequest
1 голос
/ 06 июля 2011

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

Kernel.Get<ISomething>();

на неисправной привязке, произойдет сбой с исключением, но если я использую внедрение свойства:

[Inject]
public ISomething Something { get; set;}

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

1 Ответ

1 голос
/ 15 августа 2011

Это просто не правильно.Хотя внедрение конструктора предпочтительнее (как комментарии Remo), если Ninject видит атрибут свойства [Inject] и не имеет привязки, он выдает ActivationException.

Вотпример.

Зависимость:

public interface IHello
{
    void SayHello();
}

public class Hello : IHello
{
    public void SayHello()
    {
        Console.WriteLine("Hello world!");
    }
}

Зависимый класс:

public class MyApp : IApp
{
    public virtual void Run()
    {
        Hello.SayHello();
    }

    [Inject]
    public IHello Hello { get; set; }
}

Основная программа:

class Program
{
    static void Main(string[] args)
    {
        var kernel = new StandardKernel();
        kernel.Bind<MyApp>().ToSelf();
        //kernel.Bind<IHello>().To<Hello>();
        var app = kernel.Get<MyApp>();
        app.Run();
    }
}

Если вы запустите это, выполучите следующее исключение:

Error activating IHello  
No matching bindings are available, and the type is not self-bindable.  
Activation path:  
  2) Injection of dependency IHello into property Hello of type MyApp  
  1) Request for MyApp  

Раскомментируйте строку kernel.Bind<IHello>().To<Hello>() выше, и она будет работать правильно.

Как прокомментирует Рубен, Ninject будет "молчать" только в том случае, если вы добавите [Optional] до [Inject] -ед собственности.Это потому, что вы сказали Ninject, что отсутствующая привязка не ошибка, а ожидаемое условие.В противном случае внедрение свойства работает точно так же, как внедрение конструктора.


Я подозреваю, что вы, возможно, совершаете типичную ошибку для людей, плохо знакомых с внедрением зависимости: создание зависимого класса (с [Inject]ed) с new и предполагая, что инъекция "просто происходит".Это не работает таким образом.

Чтобы Ninject или любая другая библиотека DI работали с магией, вы должны создать экземпляр контейнера с корнем привязки -другими словами, какой бы класс не содержал , свойство Something само должно быть создано с использованием kernel.Get<ClassContainingSomething>().

...