Lar*_*fax 13 c# dependency-injection simple-injector asp.net-web-api owin
我正在使用Owin,Web API,实体框架,ASP.NET身份创建API.我使用Simple Injector作为我选择的DI框架.
在Owin启动过程中,我想用一些示例数据为我的数据库设定种子.这由一个实现类处理IDatabaseInitializer,看起来像这样:
public class MyDbInitializer : DropCreateDatabaseAlways<MyDataContext>
{
private readonly IUserManager _userManager;
public MyDbInitializer(IUserManager userManager)
{
_userManager = userManager;
}
protected override void Seed(MyDataContext context)
{
SeedIdentities();
}
private void SeedIdentities()
{
var user = new User
{
UserName = "someUsername",
Email = "some@email.com"
};
_userManager.CreateAsync(user, "Password");
}
Run Code Online (Sandbox Code Playgroud)
IUserManager是ASP.NET Identiy UserManager类的代理,它间接依赖于IUnitOfWork.如果你想知道,IUserManager注册如下:
container.Register(typeof(IUserManager),
() => container.GetInstance<IUserManagerFactory>().Create());
Run Code Online (Sandbox Code Playgroud)
因为我想根据Web API请求使用单个工作单元,所以我已经注册了IUnitOfWork以下内容:
container.RegisterWebApiRequest<IUnitOfWork, MyUnitOfWork>();
Run Code Online (Sandbox Code Playgroud)
除了解析类中的IUserManager依赖项之外,这对于所有事情都很好MyDbInitializer.在应用程序启动期间,SimpleInjector失败并出现以下ActivationException:
SimpleInjector.ActivationException was unhandled by user code
HResult=-2146233088
Message=The registered delegate for type IUserManagerFactory threw an exception. The IUnitOfWork is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request.
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance[TService]()
at Project.WebApi.CompositionRoot.SimpleInjectorCompositionRoot.<RegisterSecurityDependencies>b__c() in c:\code\Project\Project.WebApi\CompositionRoot\SimpleInjectorCompositionRoot.cs:line 130
at lambda_method(Closure )
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
InnerException: SimpleInjector.ActivationException
HResult=-2146233088
Message=The IUnitOfWork is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request.
Source=SimpleInjector
StackTrace:
at SimpleInjector.Scope.GetScopelessInstance[TService,TImplementation](ScopedRegistration`2 registration)
at SimpleInjector.Scope.GetInstance[TService,TImplementation](ScopedRegistration`2 registration, Scope scope)
at SimpleInjector.Advanced.Internal.LazyScopedRegistration`2.GetInstance(Scope scope)
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
InnerException:
Run Code Online (Sandbox Code Playgroud)
我猜Owin Startup.cs类被认为是在Web API请求生命周期之外,并且数据库初始化程序中的构造函数注入失败,因为它是由Startup.cs类调用的.
我不确定如何解决这个问题.我应该使用混合生活方式进行注册IUnitOfWork,还是有更好的解决方案?
Ste*_*ven 26
你是对的.在启动期间,没有Web API请求.幸运的是,WebApiRequestLifestyle(所使用的RegisterWebApiRequest扩展方法)使用ExecutionContextLifestyle下盖,所以它是非常简单的"模拟" web请求如下:
// using SimpleInjector.Extensions.ExecutionContextScoping;
using (container.BeginExecutionContextScope())
{
var initializer = container.GetInstance<MyDbInitializer>();
intializer.InitializeDatabase();
}
Run Code Online (Sandbox Code Playgroud)