Autofac OWIN Web API current scope - asp.net-web-api

In a OWIN Web API method you can get the current scope within a Web API method like so...
public IHttpActionResult GetTaxRate()
{
var scope = Request.GetOwinContext().GetAutofacLifetimeScope();
ISomething mySomething = scope.Resolve<ISomething>();
Is there anyway to get the current scope through a static method instead of a member on the ApiController?

In short: Nope.
Autofac puts its request scope in the OWIN context so it can be shared across middleware components, so the question of how to access the Autofac-specific scope from an OWIN context is more a question of "How do you get the OWIN context?" OWIN doesn't have a static mechanism like HttpContext, so you're stuck there. That's not an Autofac issue, that's the design of OWIN.
Web API in particular also doesn't have a static notion of something like HttpContext. That's a Web API restriction, not an Autofac restriction. The request scope (and other request context things) in Web API flows with the request message. There's some Autofac-specific doc on this here but, again, this isn't an Autofac-specific issue - it's the design of Web API.

Related

VS2013 (RTW): Authentication differences in SPA template vs MVC5 template?

I've been playing with the new ASP.NET identity offerings in the VS2013 RTW MVC template (for "indivual user accounts"), and it works great: I am able to integrate Facebook login while customizing the way the data is serialized.
All well and good, but I noticed that if I create a new SPA app (instead of MVC), the authentication story seems very different. As an example:
From the SPA template:
public AccountController()
: this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
{
}
public AccountController(UserManager<IdentityUser> userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
From the MVC template:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
This is just the difference in constructors of the Account controller. There are many, many other differences as well. With the MVC version I was able to easily derive my own context class from ApplicationDBContext, and use that to store my own tables alongside the authentication tables. I couldn't figure out how to customize the data storage in the SPA template.
Also, the SPA template includes and uses this class:
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
The MVC template doesn't define (or use) this class.
I don't understand why there needs to be any differences at all between an MVC template and an SPA template.
Could anyone give me some guidance as to why authentication is handled so differently in these two templates? Starting a project from scratch, is there a preferred path to follow between the two? (It seems like the code in the MVC template is best, especially in terms of customizing how the data is stored by defining a custom EF Context class.)
Thanks...
-Ben
Take MVC and SPA project templates as Controller vs ApiController implementation sample.
As well as CookieAuthentication and oAuthAuthentication.
MVC uses Controller at the first request as well as all subsequent requests (having request defined Action Methods).
SPA uses Controller at the first request to SPA and all other interactions are handled by ApiController.
MVC uses cookie authentication.
SPA uses oAuth authentication.
Now in real apps, we need to take mix of both. Stating this, you can use the IdentityModel.cs (ApplicationDBContext) and it's customized copy of MVC project in your SPA too.
In oAuth implementation, the token is issued in GrantResourceOwnerCredentials method of ApplicationOAuthProvider. The user verification uses the same database of Identity framework by default. Moreover, oAuth provide authentication check in ApiController. In the sample implementation, oAuth's ResourceOwner flow is provided where user's username and password are verified.
In my opinion, templates are starting point examples.
I did notice the same thing when I first looked at all the posts about changing the model for the user and I couldn't find the model in the SPA template. Of course, the difference as #jd4u pointed out is that one is based on Controller and the other on ApiController.
So, I decided to see what it would take to make the SPA solution use the same Identity Model extension as the MVC template. I created a post that goes through the process that I went through. There is a link at the bottom to download the code from GitHub.

The request lifetime scope cannot be created because the HttpContext is not available

Having a hard time trying to setup AutoFac with some async non httprequest.
I have the following on App_Start
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<sfEntities>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterGeneric(typeof(sfRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerHttpRequest();
builder.RegisterType<EmailServices>().As<IEmailServices>().InstancePerHttpRequest();
builder.RegisterType<UserServices>().As<IUserServices>().InstancePerHttpRequest();
builder.RegisterType<ChatServices>().As<IChatServices>().InstancePerHttpRequest();
builder.RegisterType<DefaultFormsAuthentication>();
builder.RegisterType<WebSecurity>();
builder.RegisterType<Chat>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls.
p.s.: UnitOfWork pass the EF DbContext between services to ensure that the same instance is used and to dispose properly. If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
The following code throws the following exception:
Timer timer = new Timer(new TimerCallback(OnTimer), null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
private static void OnTimer(object o)
{
using (var timerScope = AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope())
{
var chatServices = timerScope.Resolve<IChatServices>();
chatServices.MarkInactiveUsers();
}
}
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
On SignalR, the following code throws the following exception:
SignalR.GlobalHost.DependencyResolver.Register(typeof(Chat), () => new Chat(DependencyResolver.Current.GetService<IUnitOfWork>(), DependencyResolver.Current.GetService<IChatServices>(), DependencyResolver.Current.GetService<IUserServices>()));
The request lifetime scope cannot be created because the HttpContext is not available
Thanks in advance!
Having a hard time trying to setup AutoFac with some async non httprequest.
For non-http requests, or more specifically, for non-ASP.NET pipeline requests (like WCF or ServiceStack), you should definitely change all InstancePerHttpRequest() code to InstancePerLifetimeScope(). You can and should do this because InstancePerLifetimeScope() will make it resolvable in both ASP.NET pipeline and non-ASP.NET pipeline contexts.
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls... If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
Yes, there should be more than one instance of UnitOfWork, but you can achieve that with a single registration that should be scoped to InstancePerLifetimeScope():
Example:
builder.RegisterType<NhUnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
The IChatServices service is registered as InstancePerHttpRequest and will therefore only be available within the http request lifetime scope. You are resolving from the application scope which have no "access" to the current request and therefore fail with the error you mention. So yes, to get the timer to work you must register the service in the application scope.
Basically, you can have request scoped services that access application scoped services, but not the other way around.
Question is: what is UnitOfWork.SaveChanges do and what "problems" do you get? Please elaborate.

ASP .Net 4 Web Api RC + Autofac manual resolving

I'm trying to use depedency resolver inside a Web Api method. This worked fine and works fine with classic ASP.NET MVC with the DepedencyResolver.GetService()
But I can't get this to work inside WepApi methods.
My registration register all instances as InstancePerApiRequest and if I add any of all the types I have registred in my bootstrapper on the constructor of my WebAPiConroller thay inject fine but not anymore when calling them inside.
Like this in my say Get Method
var userRepository = (IUserRepositoryu)GlobalConfiguration
.Configuration.DependencyResolver.GetService(typeof(IUserRepository));
I got the no scope WebRequest error. The strange thing is that it worked fine in Beta before they change it all to the GlobalConfiguration.
So my question is, how can I activate my Autofac registered assemblies in the lifetime scope of my webAPi as before?
My error:
"No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself."
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolver;
In Web API the global dependency resolver is used to access global instances. Per-request services come from a dependency scope that Web API creates to handle the request. I'm not sure that there is any way in Web API to access the current dependency scope - it would be interesting to know.
The best option here is to just use dependency injection rather than calling the resolver directly like this. Which part of your code needs to make this call?
AutoFac has integration with ASP.NET WebAPI consider to use it.
Also dependecy resolver for WebAPi is slightly different to ASP.NET MVC, so make shure, that you have implemented resolver suitable for WebAPI and added it to WebAPI configuration.
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
As the error indicated, you must always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime. The correct way is getting the dependency from current web api request:
// Get the request lifetime scope so you can resolve services.
var requestScope = Request.GetDependencyScope();
// Resolve the service you want to use.
var userRepository = requestScope.GetService(typeof(IUserRepository)) as IUserRepository;
See more from Autofac offical documentations:
http://docs.autofac.org/en/latest/integration/webapi.html#standard-web-api-filter-attributes-are-singletons

asp.net web api generate url for a resource

i am trying to generate a url for a resource using asp.net web api.
I can do that pretty easily in side ApiController, but what about I am not in the ApiController context?
The long way is to get the request, dig out the Configuration and the RouteData from the properties collection, create yourself a ControllerContext and then you can use UrlHelper to general Urls.
There may be an easier way, but I haven't found it yet.

How to enable Dependency Injection for ServiceRoute in MVC3 and WCF Web API

I am creating a MVC3 website that will expose a REST API using WCF Web API.
To register routes to the REST API I add code to the Global.asax similar to the code below.
routes.MapServiceRoute<RelationsService>("relations");
This works well enough but i need to use a DI approach to inject the dependencies that the Service depends on.
As you can see in the code above the MVC framework is creating the instance of the RelationsService but this should be done by the DI container.
Does anyone know how to configure MVC3 so that my own DI container is used for creating the instances of the Services?
You have to extend your current service registration call with an IHttpHostConfigurationBuilder that has been created with an IResourceFactory.
var configurationBuilder = HttpHostConfiguration.Create()
.SetResourceFactory(new ResourceFactory());
routes.MapServiceRoute<RelationsService>("relations", configurationBuilder);
Then if you for instance use StructureMap as preferred IoC/DI tool you can just ask for the service in the GetInstance method.
public class ResourceFactory : IResourceFactory
{
public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
{
return ObjectFactory.GetInstance(serviceType);
}
}

Resources