我刚刚开始尝试使用Web Api 2和StructureMap,已经安装了StructureMap.MVC4 Nuget包.在我尝试注册用户之前,一切似乎都运行良好.当IHttpControllerActivator的这个实现试图实例化一个控制器时,我得到了这个错误:
public class ServiceActivator : IHttpControllerActivator { public ServiceActivator(HttpConfiguration configuration) { } public IHttpController Create(HttpRequestMessage request , HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = ObjectFactory.GetInstance(controllerType) as IHttpController; return controller; } }
我得到的错误是:
StructureMap Exception Code: 202 No Default Instance defined for PluginFamily Microsoft.AspNet.Identity.IUserStore`1[[Microsoft.AspNet.Identity.EntityFramework.IdentityUser, Microsoft.AspNet.Identity.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Microsoft.AspNet.Identity.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
我理解错误是什么,但不完全确定如何解决它.假设StructureMap中的默认扫描程序找不到IUserStore的默认实现是否正确?这是我使用的初始化代码:
ObjectFactory.Initialize(x => x.Scan(scan => { scan.AssembliesFromApplicationBaseDirectory(); scan.WithDefaultConventions(); }));
有什么想法吗?谢谢.
编辑:我想我可能用这个解决了最初的问题:
x.For>() .Use >();
但现在还有另一个默认实例StructureMap无法解决 - dbcontext.这是我收到的下一条错误消息:
ExceptionMessage=StructureMap Exception Code: 202 No Default Instance defined for PluginFamily System.Data.Entity.DbContext, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
现在我真的迷路了......
该WithDefaultConventions()
调用不会获取您的DbContext和AspNet Identity实现.你会想看一些像SingleImplementationsOfInterface()
和的其他方法ConnectImplementationsToTypesClosing
.
默认情况下,当我设置我的StructureMap容器时,我将进行以下配置,以确保StructureMap始终将我首选类的接口和基类解析为我的实际首选类:
ioc.For<MyDbContext>().HybridHttpOrThreadLocalScoped().Use<MyDbContext>(); ioc.For<DbContext>().HybridHttpOrThreadLocalScoped().Use<MyDbContext>();
对于新的AspNet Identity类,只需将它们为开箱即用的通用类子类化:
public class MyUserManager : UserManager<MyUser> { } public class MyUserStore : UserStore<MyUser> { }
然后再次确保StructureMap知道这些:
ioc.For<IUserStore<MyUser>>().Use<MyUserStore>(); ioc.For<UserStore<MyUser>>().Use<MyUserStore>(); ioc.For<UserManager<MyUser>>().Use<MyUserManager>();
通常,您不必使用StructureMap显式注册每个类,但是对于我的DbContext和Identity类,我更喜欢为维护目的注册这些明确的类.
ericb:我可以看到你发布的内容的目的,但我无法让它发挥作用.MyUserManager类声明"public class MyUserManager:UserManager {}"抱怨UserManager接口不包含带0参数的构造函数?
任何帮助将不胜感激!
PS.这绝不是一个答案,但我不够资格,不幸的是只是评论你的答案!
更新:在此处找到解决方案:依赖注入结构图ASP.NET身份MVC 5
为清楚起见,我们在IoC文件中用以下内容替换了上述任何内容:
x.For<Microsoft.AspNet.Identity.IUserStore<ApplicationUser>>() .Use<Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>>(); x.For<System.Data.Entity.DbContext>().Use(() => new ApplicationDbContext());
我确信我们错过了ericb用他的解决方案获得的一些额外好处,但我们没有利用任何可以利用它们的东西.