У меня была точно такая же проблема:
Иметь общий репозиторий:
public interface IRepository<TEntity> : IDisposable where TEntity : class
{ }
и конкретная реализация:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{ }
, который я хотел внедрить в конструктор контроллеров во время выполнения, где TEntity будет моделью, относящейся к этому контроллеру:
public FooBarController(IRepository<FOO_BAR_TYPE> repository)
{
_repo = repository;
}
Контроллер затем использовал бы Репозиторий "_repo" для обновления Модели:
//
// POST: /EmergencyServiceType/Create
[HttpPost]
public ActionResult Create(FOO_BAR_TYPE foobar)
{
if (ModelState.IsValid)
{
// GetNextSequenceValue() deals with Oracle+EF issue with auto-increment IDs
foobar.FOO_BAR_ID = _repo.GetNextSequenceValue();
_repo.Add(foobar);
_repo.SaveChanges();
return RedirectToAction("Index");
}
return View(foobar); // display the updated Model
}
simonjreid объяснил мне ответ: пришлось добавить ObjectContext в конфигурацию StructureMap (целью репозитория было обернуть контекст, сгенерированный EntityFramework, который я назвал MyContextWrapper. Поэтому, потому что репозиторий зависел от MyContextWrapper, который в свою очередь зависит от ObjectContext):
// This avoids 'No Default Instance for ...DbConnection' exception
x.For<System.Data.Objects.ObjectContext>().Use<MyContextWrapper>();
x.For<System.Web.Mvc.IController>().Use<Controllers.FooBarController>().Named("foobarcontroller"); // note that Named is required and is Case Sensitive
Однако теперь я получаю исключение времени выполнения StructureMap:
Код исключения StructureMap: 205
Отсутствует запрошенное свойство экземпляра "connectionString"
После прочтения поста Джереми Миллера Нежный быстрый старт (справа внизу) я обнаружил, что вы можете определить, какие аргументы передать в конструктор ваших зарегистрированных типов, т.е. мне нужно было передать в Connection Строка для конструктора класса MyCustomContext (вот полный список того, как я инициализирую ObjectFactory:
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["MyContextWrapper"].ConnectionString;
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
// Make sure BUSINESS_DOMAIN assembly is scanned
scan.AssemblyContainingType<BUSINESS_DOMAIN.MyContextWrapper>();
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
// 'connStr' below is a local variable defined above
x.For<System.Data.Objects.ObjectContext>()
.Use<MyContextWrapper>()
.Ctor<string>().Is(connStr);
x.For<System.Web.Mvc.IController>().Use<Controllers.FooBarController>().Named("foobarcontroller");
});
И БУМ! Теперь можно создать экземпляр моего контроллера во время выполнения с помощью StructureMap и заставить его внедрить экземпляр IRepository ... счастливых дней.