我有一个界面IGenericRepository<TEntity> where TEntity : IEntity
和一个实现GenericRepository<TEntity> where TEntity : Entity
。
我正在尝试使用StructureMap将特定的IGenericRepository<Section>
注入到类中:
ObjectFactory.Initialize(x =>
{
x.For(typeof(IGenericRepository<>)).Use(typeof(GenericRepository<>));
});
但是当我尝试使用ObjectFactory.GetInstance<IGenericRepository<Section>>();
时,我得到了:
StructureMap异常代码:202没有为PluginFamily System.Data.Common.DbConnection定义默认实例
为什么会这样或者我做错了?
提前致谢,
西蒙
答案 0 :(得分:8)
您在GenericRepository的构造函数中收到一个DbConnection,它是一个抽象类,并没有配置SM来知道应该使用哪个特定类。
即:
ObjectFactory.Initialize(x =>
{
x.For(typeof(DbConnection)).Use(typeof(SqlConnection));
x.For(typeof(IGenericRepository<>)).Use(typeof(GenericRepository<>));
});
答案 1 :(得分:4)
我有同样的问题:
拥有通用存储库:
public interface IRepository<TEntity> : IDisposable where TEntity : class
{ }
和具体实施:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{ }
我想在运行时注入Controllers的构造函数,其中TEntity将是与该Controller相关的模型:
public FooBarController(IRepository<FOO_BAR_TYPE> repository)
{
_repo = repository;
}
然后,Controller将使用Repository“_repo”来更新Model:
//
// 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配置中(Repository的目的是包装由EntityFramework生成的Context,我称之为MyContextWrapper。因此,Repository依赖于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”
在阅读Jeremy Miller A Gentle Quickstart的帖子后(右下方)我发现你可以定义传入你注册类型的构造函数的参数,即我需要将连接字符串传递给构造函数的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");
});
和BOOM!现在可以让我的Controller在运行时由StructureMap实现,并让它注入一个IRepository实例......快乐的日子。
答案 2 :(得分:3)
你的构造函数是什么样的GenericRepository<>
?
它或其中一个依赖项期望SM无法创建DbConnection
。