Resolving IOwinContext in MVC5 application using Autofac

拈花ヽ惹草 提交于 2019-12-03 10:17:51

问题


I have trouble using MembershipReboot with the new ASP MVC5 template and Autofac. I have used the default MVC5 template to set up the site and then tried to wire up the MembershipReboot framework as a replacement for the ASP Identity framework that ships with the template.

This issue I am having is trying to resolve an IOwinContext from the Autofac container. Here is my wiring in the Startup class (cut down to basics). This is the wiring used in the samples for the MembershipReboot Owin application (except there he uses 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();
            }
        });
    }

And here is my controller with the dependency specified in the controller constructor.

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();
    }
}

It seems I need to wrap my Autofac container in an AutofacDependencyResolver in order for the MVC framework to use the container to resolve components. This is the only major difference from the Nancy Owin sample and my use in MVC5.

When I do this, it then seems (from my Tracing) as if the dependency is being resolved without first going through the OWIN middleware stack so the IOwinContext is never registered.

What am I doing wrong here?

UPDATE:

Brock, your new sample works perfectly when I migrate the configuration over to my project. Just for my understanding, it seems that this line in your new sample registers the current OwinContext with the container and that is what was missing previously.

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

Is that


回答1:


There's a newer sample that does DI with AutoFac for MVC:

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

See if this helps.

If you don't want to use HttpContext.Current you could do something like this:

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();
    }
}); 

This is what we're doing internally for some of our apps. You'd need to wire up your Web API service resolver to look for "idsrv:AutofacScope". Tugberk has a post on this:

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



来源:https://stackoverflow.com/questions/21703268/resolving-iowincontext-in-mvc5-application-using-autofac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!