使用Autofac解析MVC5应用程序中的IOwinContext



我在将MembershipReboot与新的ASP MVC5模板和Autofac一起使用时遇到问题。我使用了默认的MVC5模板来设置网站,然后尝试连接MembershipReboot框架,以替换该模板附带的ASP Identity框架。

我遇到的这个问题是试图解决Autofac容器中的IOwinContext。这是我在Startup类中的连线(简化为基础)。这是MembershipReboot Owin应用程序样本中使用的布线(除了他使用Nancy)。

public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.Register(c => new DefaultUserAccountRepository())
.As<IUserAccountRepository>()
.As<IUserAccountQuery>()
.InstancePerLifetimeScope();
builder.RegisterType<UserAccountService>()
.AsSelf()
.InstancePerLifetimeScope();
builder.Register(ctx =>
{
**var owin = ctx.Resolve<IOwinContext>();** //fails here
return new OwinAuthenticationService(
MembershipRebootOwinConstants.AuthenticationType,
ctx.Resolve<UserAccountService>(),
owin.Environment);
})
.As<AuthenticationService>()
.InstancePerLifetimeScope();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
ConfigureAuth(app);
app.Use(async (ctx, next) =>
{
using (var scope = container.BeginLifetimeScope(b =>
{
b.RegisterInstance(ctx).As<IOwinContext>();
}))
{
ctx.Environment.SetUserAccountService(() => scope.Resolve<UserAccountService>());
ctx.Environment.SetAuthenticationService(() => scope.Resolve<AuthenticationService>());
await next();
}
});
}

这是我的控制器,在控制器构造函数中指定了依赖项。

public class HomeController : Controller
{
private readonly AuthenticationService service;
public HomeController(AuthenticationService service)
{
this.service = service;
}
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}

似乎我需要将Autofac容器封装在AutofacDependencyResolver中,以便MVC框架使用该容器来解析组件。这是Nancy Owin样本和我在MVC5中使用的唯一主要区别。

当我这样做时,(从我的跟踪中)似乎在不首先经过OWIN middleware堆栈的情况下就解决了依赖关系,因此IOwinContext永远不会注册。

我在这里做错了什么?

更新:

Brock,当我将配置迁移到我的项目中时,您的新示例非常有效。据我所知,新样本中的这一行似乎向容器注册了当前OwinContext,而这正是之前所缺少的。

builder.Register(ctx=>HttpContext.Current.GetOwinContext()).As<IOwinContext>();

那是吗

有一个新的示例使用AutoFac为MVC进行DI:

https://github.com/brockallen/BrockAllen.MembershipReboot/blob/master/samples/SingleTenantOwinSystemWeb/SingleTenantOwinSystemWeb/Startup.cs

看看这是否有帮助。

如果你不想使用HttpContext.Current,你可以这样做:

app.Use(async (ctx, next) =>
{
// this creates a per-request, disposable scope
using (var scope = container.BeginLifetimeScope(b =>
{
// this makes owin context resolvable in the scope
b.RegisterInstance(ctx).As<IOwinContext>();
}))
{
// this makes scope available for downstream frameworks
ctx.Set<ILifetimeScope>("idsrv:AutofacScope", scope);
await next();
}
}); 

这就是我们在内部为一些应用程序所做的。您需要连接Web API服务解析程序来查找"idsrv:AutofacScope"。Tugberk有一个关于这个的帖子:

http://www.tugberkugurlu.com/archive/owin-dependencies--an-ioc-container-adapter-into-owin-pipeline

相关内容

  • 没有找到相关文章

最新更新