2

Я следующие this post чтобы узнать о DI с AutoFac. Мой контекст DB зарегистрирован в Startup.cs так:Как зарегистрировать интерфейс для конструктора EntityFramework.UserStore <TUser>?

builder.RegisterType<MyDb>().As<IMyDbCtx>().InstancePerRequest(); 

я следовал инструкциям, чтобы создать класс ApplicationUserStore и зарегистрировал этот тип, как так:

builder.RegisterType<ApplicationUserStore>().As<IUserStore<ApplicationUser>>().InstancePerRequest(); 

Это все было прекрасно, пока я понял, что ApplicationUserStore ожидает конкретного DbContext в его конструкторе передать его базовый конструктор:

public ApplicationUserStore(MyDb context) 
      : base(context) 
     { 
     } 

Когда я запустить приложение и попробуйте загрузку Регис трация страница, это ошибка я вижу:

Ни один из конструкторов, найденных с «Autofac.Core.Activators.Reflection.DefaultConstructorFinder» по типу «TestApp.Service.IdentityConfig.ApplicationUserStore» не может быть вызван с имеющимися услуг и параметров: Не удается разрешить параметр 'TestApp.Data.MyDb context' конструктора 'Void .ctor (MyApp.Data.MyDb)'.

Это нарушение, я предполагаю, потому что я уже настроил MyDB как IMyDbCtx, поэтому он не будет принимать конкретный тип. Это хорошо, потому что я не хочу быть непоследовательным, вводя абстракции в некоторых местах и ​​реализации в других.

Есть ли у кого-нибудь идеи о том, как я могу передать IMyDbCtx в UserStore ctor, в частности с помощью AutoFac?

ответ

0

Вы можете зарегистрировать свой тип MyDB под псевдонимами, как многие, как вы хотите:

builder.RegisterType<MyDb>() 
    .As<MyDb>() 
    .As<IMyDbCtx>() 
    .InstancePerRequest(); 

В этом случае Autofac может разрешить Application User Store. Но он убивает всю идею инъекции зависимости, потому что вы кормите конкретный тип.

+0

'DbContext' от Entity Framework не значит быть позади интерфейса таким образом. И «Injection Dependency» не означает создание интерфейса для каждого класса, который у вас есть. – trailmax

+0

Да, я знаю. Но бессмысленно иметь интерфейс и внедрять реализацию, если только это не очень конкретный случай (например, интерфейс предназначен для инъекции другими модулями, но некоторые внутренние типы могут внедрять реализацию). Я рекомендую стартеру темы убедиться, что это «конкретный» случай. И если это не так - попробуйте избавиться от интерфейса или внедрить реализацию. –

1

Это не идеальное решение, но я решил бросить интерфейс к конкретному типу, когда параметр передается в базовый конструктор:

общественного ApplicationUserStore (IMyDbCtx контекст) : базовый ((MyDB) контекст) { }

+0

Какой смысл иметь интерфейс через 'DbContext'? Зарегистрируйте свой DbContext '.AsSelf()' и введите его прямо. Что делает ваш интерфейс 'IMyDbCtx', так или иначе? – trailmax

+0

FYI Я новичок и стараюсь найти хороший дизайн. UoW как контракт, описанный здесь (http://stackoverflow.com/questions/21349950/entity-framework-6-code-first-is-repository-implementation-a-good-one), звучит как хорошая идея.Я пытался максимально скрыть спецификацию EF (DbContext) на моем уровне обслуживания, но это создает проблему. – MvvM

+0

EF уже внедряет UoW, не изобретайте свои собственные, особенно для классов, которые вы не контролируете, которые ожидают ввода определенного DbContext. – trailmax

Смежные вопросы