Ладно, недавно я читал ниндзя, но у меня возникли проблемы с пониманием того, что делает лучше, чем то, что на вики-странице они называют "DI" для бедняков. Печально то, что я просмотрел все их страницы в вики и до сих пор не понимаю = (.
Обычно я оборачиваю свои классы обслуживания в фабричный шаблон, который обрабатывает DI следующим образом:
public static class SomeTypeServiceFactory
{
public static SomeTypeService GetService()
{
SomeTypeRepository someTypeRepository = new SomeTypeRepository();
return = new SomeTypeService(someTypeRepository);
}
}
Что мне кажется очень похожим на модули:
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
Где каждый класс будет иметь свой связанный модуль, и вы привязываете его конструктор к конкретной реализации. Несмотря на то, что пустой код на 1 строку меньше, я просто не вижу преимущества, каждый раз, когда вы добавляете / удаляете конструкторы или изменяете реализацию конструктора интерфейса, вам придется менять модуль почти так же, как на фабрике. нет? Так что не вижу здесь преимущества.
Тогда я подумал, что смогу придумать общую фабрику, основанную на соглашениях, вот так:
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
TServiceClass serviceClass = null;
string repositoryName = typeof(TServiceClass).ToString().Replace("Service", "Repository");
Type repositoryType = Type.GetType(repositoryName);
if (repositoryType != null)
{
object repository = Activator.CreateInstance(repositoryType);
serviceClass = (TServiceClass)Activator.CreateInstance(typeof (TServiceClass), new[]{repository});
}
return serviceClass;
}
Однако это дерьмово по двум причинам: 1) оно тесно зависит от соглашения об именах, 2) предполагается, что в хранилище никогда не будет никаких конструкторов (не так), и единственный конструктор службы будет соответствующим репозиторием (также не правда). Мне сказали «эй, это то место, где вы должны использовать контейнер IoC, здесь было бы здорово!» И поэтому мое исследование началось ... но я просто не вижу его и испытываю трудности с пониманием. ..
Есть ли какой-нибудь способ, с помощью которого ninject может автоматически разрешать конструкторы класса без специального объявления, так что было бы замечательно использовать его в моей универсальной фабрике (я также понимаю, что мог бы просто сделать это вручную, используя отражение, но это удар по производительности и процент говорит прямо на своей странице, что они не используют отражение).
Прочтение этого вопроса и / или демонстрация того, как его можно использовать на моей общей фабрике, было бы очень полезно!
РЕДАКТИРОВАТЬ: Ответ
Так что благодаря приведенному ниже объяснению я был в состоянии полностью понять удивительность ninject, и моя общая фабрика выглядит так:
public static class EntityServiceFactory
{
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
IKernel kernel = new StandardKernel();
return kernel.Get<TServiceClass>();
}
}
Довольно круто. Все обрабатывается автоматически, поскольку конкретные классы имеют неявное связывание.