2015-08-07 3 views
0

Использование WebAPI и интерфейсов для моего Repos, AutoFac, похоже, пытается создать экземпляр моего UserRepoitory, но когда он пытается создать экземпляры, он застревает в своих конструкторах.AutoFac и разрешающие объекты по цепочке

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on 
type 'Db.UserRepository' can be invoked with the available services 
and parameters: Cannot resolve parameter 'Db.DbContext context' of constructor 'Void .ctor(Db.DbContext)'. 

public class UserRepository : IUserRepository 
    { 
     DbContext db = null; 

     public UserRepository(DbContext context) 
     { 
      db = context; 
     } 
    } 

    public class FindABriefContext : DbContext 
    { 
     public FindABriefContext() : base("FindABriefContext") 
     {} 
    } 

Ничего особенного в моей DI код ..

public static void RegisterContainer() 
     { 
      var builder = new ContainerBuilder(); 

      builder.RegisterApiControllers(typeof(UserController).Assembly); 

      //var asm = typeof(IUserRepository).Assembly; 
      builder.RegisterAssemblyTypes(typeof(UserRepository).Assembly) 
       .Where(x => x.Name.EndsWith("Repository")).AsImplementedInterfaces(); 

      var container = builder.Build(); 
      GlobalConfiguration.Configuration.DependencyResolver= new AutofacWebApiDependencyResolver(container); 

     } 

ответ

0

Вам необходимо пройти контекст в качестве параметра в вашем хранилище.

Из autofac документации:

builder.RegisterType<ConfigReader>() 
     .As<IConfigReader>() 
     .WithParameter(new TypedParameter(typeof(string), "sectionName")); 

Или я хотел бы использовать фабрику и просто вводить завод вместо инъекций всех ваших хранилищ.

public class RepositoryFactory : IRepositoryFactory 
{ 
     public IRepository<T> CreateRepository<T>() where T : class 
     { 
      var yourContext = new SomeContext(); //can also be injected 
      return new Repository<T>(yourContext); 
     } 
} 

Тогда вы просто вводите единый завод.

builder.RegisterType<RepositoryFactory>().As<IRepositoryFactory>(); 
+0

Factory Pattern работает для меня - я дам, что выстрел ... и доложить. –

+0

Infact - думая об этом, он не работает для меня, я не использую общие репозитории - я вернусь в Unity. –

+0

Есть еще возможность использовать первую часть ответа «.WithParameter» и передать свой контекст в репозитории. Так же, как у вас есть, теперь добавьте его до конца: .AsImplementedInterfaces(). WithParameter (... –

1

Для того, чтобы контейнер создавал репозиторий, он должен удовлетворять своей зависимости от DBContext. Вот почему вам нужно сообщить Autofac, как разрешить DbContext.

Просто добавьте следующую строку

builder.RegisterType<FindABriefContext>().As<DbContext>(); 

перед тем

var container = builder.Builder(); 
+0

Спасибо за это - он просто не работал для меня - спустился с 'builder.RegisterSource (новый AnyConcreteTypeNotAlreadyRegisteredSource()); 'route вместо. Спасибо! –

+0

@ Stuart.Sklinar, тогда у вас должны быть другие незарегистрированные зависимости, которые вы здесь не упомянули. Похоже, вы пытались заставить Autofac вести себя как Unity с помощью AnyConcreteTypeNotAlreadyRegisteredSource, который регистрирует ВСЕ конкретные типы, которые он может найти. Это зависит от вашего приложения, его срока службы и т. Д., Но регистрация всех типов, конечно, не является хорошей практикой. –

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