ServiceLocator/IOC in ASP.Net environment - asp.net

I have a home-grown framework that includes a simple ServiceLocator class implemented using a static Dictionary. It was developed for a WinForms environment and did what I wanted just fine.
This proves to be a disaster when using the framework in as ASP.Net framework; the Dictionary, a static variable, is instanciated upon first use and every ASP.Net application uses the same dictionary. This is NOT my design intent.
For example, the a web application attempts to register a DB Audit Service, IAuditService. Error!! The service is already registered by the first user! Just the tip of the static variable problems that can occur in a ASP.Net environment.
I have experimented with Autofac IOC. Can I avoid my static variable problems by using Autofac (or some other IOC)?
BP....

You can use an IOC framework, but if you want the object to stick around you will have to store it yourself, otherwise you will just be asking for a new object each time from the IOC Container.

I add a new instantiation type to my ServiceLocation specific to a web application.

Related

Custom ClaimsPrincipal or ClaimsIdentity (where to graft it?)

Where can I extend ASP.NET current (5.0) Identity functionality to easily resolve the integer user ID and security rights associated with a claim?
This should be available within all of my web application browser service access points (everywhere a cookie or JWT is provided), including SignalR hub, MVC controller, and WebAPI controller. It should work with OWIN Authentication.
Here are the three most-related solutions I've seen, and why they don't work:
Set HttpContext.Current.User in every call via global.asax Application_PostAuthenticateRequest. I've seen older (MVC 4) functionality that obsoletes this. I know global.asax is generally not the way to go today. I'm also using OWIN; this may not even work at all.
Override ClaimsPrincipal ClaimsAuthenticationManager.Authenticate() with the configuration <system.identityModel><identityConfiguration><claimsAuthenticationManager type = "CustomClaimsAuthenticatonManager" /> However, ClaimsAuthenticationManager is from System.Identity, which isn't even in the references of my ASP.NET 5.0 project with ClaimsAuthentication active. Instead I have references to Microsoft.AspNet.Identity.Core stuff in my project from current NuGet packages. It seems this approach is not for ASP.NET apps, or at least not current ones?
Set UserManager.ClaimsIdentityFactory to a custom ClaimsIdentityFactory, with overridden CreateAsync. This looks like this might work, but I don't see any way to graft that onto the current ASP.NET default behavior. See here: How to set a custom ClaimsPrincipal in MVC 5?

Unified MVC and Web API Controllers

I'm building a web application using ASP.NET MVC6 that needs to be accessible via a web browser (via Views), as well as from mobile applications via Web API. The thing is that I would like to avoid duplicating business logic in controllers.
I know that MVC6 controllers return an IActionResult. When used as an MVC controller, the IActionResult might be a view. When used as a Web API controller, the IActionResult might be data (such as a list of products). The same controller might have actions (two different actions) that return both views and data.
But my requirement is to have one single method which can be used to render views when called in normal way in form of website and return data when called as Web API method.
As you’re already aware, MVC Controllers and Web API Controllers are now exactly the same. They’ve been unified as of MVC 6.0.
When you say you’d like to avoid duplicate business logic in the Controllers, may I ask why is it like that in the first place?
Do you have/shouldn’t you have some sort of Class Library project acting as your Business Layer in which you store all your relevant business rules?
For example:
Contoso.Web ( MVC 6.0 application)
Contoso.Service (Class Library holding your business rules)
Contoso.Data (Class Library holding your DataContext and Entity
Framework stuff...)
Contoso.Core or Contoso.Domain (Class Library holding your domain
classes/POCOs)
In addition, you want the ability for your application to be viewed from within classic browser as much as from mobile devices. Have you considered building a SPA (Single Page Application) which gets you best of both worlds?
The SPA approach, will allow you to create Views and using a client side framework (ex: Angular) will allow you to invoke your WebAPI which in turn would invoke your Contoso.Service layer.
Unless, of course, your mobile app is a native one that only needs to invoke your WebAPI
If there is a way for an IActionResult to either return a View or some Data, the concern I have is that this IActionResult may start growing and having some discoverable logic in them which may be hard to maintain/debug in the long run.
You also increase the likelihood of regression when you modify its behavior since you’ll need to test both the Views and the mobile app.
With little I know about your project, I’d take a look at SPA approach to see if it fits your need(s).

How to return or cast the same type from web services

I've created a web service in asp.net (ASMX) for caching purposes.
The website that uses this WS, requests and gets a shared type object (that is, both the website & webservices use the same DLL that includes that object type).
but what happens is, that the website gets the response from the webservices and the type is being wrapped by the WS's name space.
for instance.
If I have in the shared DLL a class Core.Person
the webservice returns Core.Person.
the website (even it knows the core.person) will get WebServiceNS.Person
This won't allow me to cast it.
how can I still use the same original DLL namespace when getting those objects from the WS?
thanks
You should not be using ASMX services for new development. It's a legacy technology.
In addition, it has no ability to do what you want. WCF, on the other hand, can do it trivially.
One solution can be, instead of using ASMX service use WCF service. WCF service allows you to use existing structure for the webservice call. In that case you will not need to create reference of your service. You can use same Core.dll in both the projects.
If you need any help in this, post a comment.
Hope this works for you.
Actually when we add a webservice reference VS generates a stub creating classes for all the objects required by WS. (These are on the basis of WSDL file hosted on the web server). All our communication with the webservice is done using this stub. I guess you'll have to write your own copy constructor for this.

Hosting a .net assembly for COM interop with long lifetime?

I have a component (an assembly built in .net) that i need to access on (almost) every request to two different websites. One website is written in classic asp and the other one in asp.net mvc.
At the moment i reference the assembly in the asp.net solution and call it like i would any .net assembly. On the classic asp website, i call it through a COM wrapper.
This is all good, except now i need this component to actually stay alive and monitor changes to a configuration file. In my asp.net website i could keep a refence in the application scope and i guess i could register it in component services for the asp access.
Is this the best way to do it? Also, this way the component would actually be hosted twice - one instance in the asp.net application scope and one in the component services. I could perhaps instead only have it live in component services, and then instead reference it from asp.net.
I don't know - something smells fishy (and no, it's not me) - am i on the right track or do you see better alternatives?
Do you really need a long running object? You say you need to monitor configuration file changes -- when the config changes do you need to trigger some actions or do you just need to ensure that each incoming request uses the latest copy of the configuration for your component? If it is the latter then standard .NET configuration should work for you without concern for the object lifetime.
In terms of hosting, do you need to use any COM+ services? If not, then I would not use COM+. If you want one central location for your .NET component, why not register it in the GAC?
Ok so i think i found two solutions, both acceptable for this project:
1) Register it in global.asa on the Application_OnStart in the Application object like this Application("Someobject") = Server.CreateObject("Someobject")
2) Host it in component services and handle lifetime there.

When do asp.net role providers live and die?

I am working with a custom role provider in asp.net and it appears that once the provider is loaded into memory, it doesn't drop out of memory until the web application is restarted (like when the web.config file is changed and saved). Further, all of the requests to that web application seem to utilize the one instance of the role provider.
So my question is: When does asp.net create instances of role providers? And what is their life span? When does asp.net create new instances? And is there a way to force asp.net to refresh the current provider instance by dropping the old instance and creating a new one?
The design of ASP.NET assumes the providers are stateless objects. Therefore, you should design your provider in a manner that you won't need to know about when it is created and when it dies. Basically, if you really want to do that, you could put the actual logic in a different class that its creation and disposal will be handled by a proxy class that you introduce to ASP.NET.
Also, ASP.NET does not guarantee when it will create the role provider object. It's something like static constructors. You should only rely on the fact that they do exist whenever they are needed.

Resources