How IAclModule works - c#

I want to know how exactly this class IAclModule works, I mean the process it pass, it's instanceaded one each loop to verify the access for the user, or it's used the same instance each time?
I ask that because I need to implement my own logic since the default AuthorizeAttributeAclModule and XmlRolesAclModule have been wayyy to slow.
Thx.

The AclModule is instantiated by the DI (dependency injection) container. When using the internal DI container, it is instantiated by the SiteMapFactoryContainer.ResolveAclModule method. However, whether using internal or external DI, the instance is kept alive for the lifetime of the SiteMap object (and therefore by the cache) by being stored in a private field of the SiteMapPluginProvider class, which in turn is in a private field of the SiteMap class. Therefore, there is 1 instance per SiteMap which by default only gets created each time the cache expires (1 time every 5 minutes by default).
The AuthorizeAttributeAclModule has been tested pretty thoroughly and has been optimized pretty well. However, it creates an instance of the related controller class and the AuthorizeAttribute class for each node, so if your Controllers or any custom implementations of AuthorizeAttribute are doing too much work in the constructor, you could run into performance issues.
To fix this, you should aim to inject dependencies into each controller through the Controller constructor instead of doing heavy lifting inside of the constructor. If you use a dependency injection container in conjunction with a custom IControllerFactory, you can control the lifetime of the dependencies externally from the controller. As shown in the example below, when using this approach you could use the same instance of IMyRepository for every instance of MyController.
public class MyController : Controller
{
public MyController(IMyRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
this.repository = repository;
}
private readonly IMyRepository repository;
public ActionResult Index()
{
var items = this.repository.GetList()
return View(items);
}
}
That is a recommended best practice for the design of your controllers, but in a pinch, you could also request-cache your dependencies if they are expensive to create so each controller instance won't be so time-consuming to create if it is instatiated more than one time per request.
public class MyController : Controller
{
public MyController()
{
this.repository = this.GetOrCreateRepository();
}
private readonly IMyRepository repository;
private IMyRepository GetOrCreateRepository()
{
var key = "MyControllerRepository";
var result = HttpContext.Items[key];
if (result == null)
{
// If the expensive dependency wasn't already created for this request, do it now
result = new MyRepository();
// Save the instance in the request, so the next time this controller is created,
// it doesn't have to instantiate it again.
HttpContext.Items[key] = result;
}
return result;
}
public ActionResult Index()
{
var items = this.repository.GetList()
return View(items);
}
}
Also, if you have custom AuthorizeAttribute(s) you should make sure they are not doing any work except checking whether the user is authorized, delegating the real work to a handler the same way that Microsoft does.

Related

How to inject User Identity in Asp.Net web api controller constructor?

I have a controller decorated with [Authorize] attribute. I would like to accomplish the following so that I don't have to repeatedly create repository obj and pass currentUser in each method:
[Authorize]
public class HomeController : ApiController
{
Repository repo;
public HomeController()
{
var userName = User.Identity.IsAuthenticated ? User.Identity.Name : null;
repo = new Repository(userName);
}
}
I know User.Identity is not available in constructor or in Initialize method.
What is the best practice to inject authenticated user in controller constructor.
If we use dependency injection - while registering our custom created UserResolverService inside WebApiConfig.cs in Register method - User.Identity is not available at this point as well.
This is a very common issue with web api but somehow couldn't find any article showing proper solution.
Is it really achievable and if yes - can you please provide some sample code?
Here is how I worked around this (not sure how appropriate this method is, but it works).
In your BaseContoller (a controller from which all other controllers inherit from) create instance of Repository like so:
private Repository _Repository;
private Repository Repository
{
get
{
_Repository.InjectUsername(User.Identity.Name); // value is already available here
return _Repository;
}
set
{
_Repository = new Repository();
}
}
Notice how your Repository has InjectUsername method. That method will simple assign passed parameter to some Repository's property, like so:
public class Repository
{
private string Username { get; set; }
public void InjectUsername(string username)
{
Username = username;
}
}
Every time you will call some method in repository from a controller action you will inject usrename which will already exist, and you won't have to duplicate code by passing username to every method in repository every time you call it.
You can register a factory delegate and get user identity from HttpContext.Current.
Here's a sample code for simpleinjector
container.Register<IPrincipal>(() => HttpContext.Current.User);

ASP.NET OWIN vs Singleton Pattern

I'm working on a Web App where I instantiated my a Singleton class below in Startup.cs in order to be reused (more like making a programmable session):
app.CreatePerOwinContext<XYZManager>(XYZManager.Create);
But I'm encountering a problem, as soon as UserA logs in on the app, the information inside XYZManager class gets overwritten when UserB enters and vice versa when they perform some action.
The problem I think is, they're sharing the same application pool, how can this be resolve, any hack?
An meanwhile the whole essence of this approach, I want to be able to call any getter / setter of method inside XYZManager for the current logged user for example:
HttpContext.GetOwinContext().Get<XYZManager>().GetFullDetails();
But sometimes throw details for another logged on user based on operations.
public class XYZManager : IDisposable
{
private static XYZManager instance { get; set; }
public static XYZManager Create()
{
var xyzManager = instance ?? (instance = new XYZManager());
xyzManager.ApplicationDbContext = new ApplicationDbContext();
return xyzManager;
}
public string GetFullDetails () {
return "blah blah";
}
}
As described in msdn, the CreatePerOwinContext method will accept a factory method to create an instance of your class (in this cas XYZManager), and it will keep it for all same context requests with.
HttpContext.GetOwinContext().Get<XYZManager>()
So each time a new Owin Context is created (a new http request received) XYZManager.Create will be invoked. In your case this method returns the same instance, so all contexts will share that instance.
Depending if you want to share that instance for all contexts or not you should return new or the same instances. Also note, that for singleton shared instances there is a different Owin extension method that will keep the singleton for you.
Check out this answer as it explains what is the purpose of the CreatePerOwinContext method, as well as provide some examples how to create a inter context shared instance.
This is how you create Context shared service
public class XYZManager : IDisposable
{
public static XYZManager Create()
{
return new XYZManager(new ApplicationDbContext());
}
private readonly ApplicationDbContext DbContext;
public XYZManager(ApplicationDbContext dbContext)
{
DbContext = dbContext;
}
public string SomeInfo {get;set;}
public string GetFullDetails ()
{
return dbContext.getFullDetails();
}
// dispose
}
Note: Since you will be creating instances each time a new owin context is creates it is advisable, to make sure any unmanaged objects are disposed.

WebApi: Per Request Per Action DbSession using IoC, how?

Our existing database deployment has a single 'master' and a read-only replica. Using ASP.NET's Web API2 and an IoC container I want to create controller actions whose attribute (or lack there of) indicate which database connection is to be used for that request (See Controller and Services usage below)...
public MyController : ApiController
{
public MyController(IService1 service1, IService2 service2) { ... }
// this action just needs the read only connection
// so no special attribute is present
public Foo GetFoo(int id)
{
var foo = this.service1.GetFoo(id);
this.service2.GetSubFoo(foo);
return foo;
}
// This attribute indicates a readwrite db connection is needed
[ReadWrteNeeded]
public Foo PostFoo(Foo foo)
{
var newFoo = this.service1.CreateFoo(foo);
return newFoo;
}
}
public Service1 : IService1
{
// The dbSession instance injected here will be
// based off of the action invoked for this request
public Service1(IDbSession dbSession) { ... }
public Foo GetFoo(int id)
{
return this.dbSession.Query<Foo>(...);
}
public Foo CreateFoo(Foo newFoo)
{
this.dbSession.Insert<Foo>(newFoo);
return newFoo;
}
}
I know how to setup my IoC (structuremap or Autofac) to handle per request IDbSession instances.
However, I'm not sure how I would go about making the type of IDbSession instance for the request to key off the indicator attribute (or lack there of) on the matching controller's action. I assume I will need to create an ActionFilter that will look for the indicator attribute and with that information identify, or create, the correct type of IDbSession (read-only or read-write). But how do I make sure that the created IDbSession's lifecycle is managed by the container? You don't inject instances into the container at runtime, that would be silly. I know Filters are created once at startup (making them singleton-ish) so I can't inject a value into the Filter's ctor.
I thought about creating an IDbSessionFactory that would have 'CreateReadOnlyDbSession' and 'CreateReadWriteDbSession' interfaces, but don't I need the IoC container (and its framework) to create the instance otherwise it can't manage its lifecycle (call dispose when the http request is complete).
Thoughts?
PS During development, I have just been creating a ReadWrite connection for every action, but I really want to avoid that long-term. I could also split out the Services methods into separate read-only and read-write classes, but I'd like to avoid that as well as placing GetFoo and WriteFoo in two different Service implementations just seems a bit wonky.
UPDATE:
I started to use Steven's suggestion of making a DbSessionProxy. That worked, but I was really looking for a pure IoC solution. Having to use HttpContext and/or (in my case) Request.Properties just felt a bit dirty to me. So, if I had to get dirty, I might as well go all the way, right?
For IoC I used Structuremap and WebApi.Structuremap. The latter package sets up a nested container per Http Request plus it allows you to inject the current HttpRequestMessage into a Service (this is important). Here's what I did...
IoC Container Setup:
For<IDbSession>().Use(() => DbSession.ReadOnly()).Named("ReadOnly");
For<IDbSession>().Use(() => DbSession.ReadWrite()).Named("ReadWrite");
For<ISampleService>().Use<SampleService>();
DbAccessAttribute (ActionFilter):
public class DbAccessAttribute : ActionFilterAttribute
{
private readonly DbSessionType dbType;
public DbAccessAttribute(DbSessionType dbType)
{
this.dbType = dbType;
}
public override bool AllowMultiple => false;
public override void OnActionExecuting(HttpActionContext actionContext)
{
var container = (IContainer)actionContext.GetService<IContainer>();
var dbSession = this.dbType == DbSessionType.ReadOnly ?
container.GetInstance<IDbSession>("ReadOnly") :
container.GetInstance<IDbSession>("ReadWrite");
// if this is a ReadWrite HttpRequest start an Request long
// database transaction
if (this.dbType == DbSessionType.ReadWrite)
{
dbSession.Begin();
}
actionContext.Request.Properties["DbSession"] = dbSession;
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var dbSession = (IDbSession)actionExecutedContext.Request.Properties["DbSession"];
if (this.dbType == DbSessionType.ReadWrite)
{
// if we are responding with 'success' commit otherwise rollback
if (actionExecutedContext.Response != null &&
actionExecutedContext.Response.IsSuccessStatusCode &&
actionExecutedContext.Exception == null)
{
dbSession.Commit();
}
else
{
dbSession.Rollback();
}
}
}
}
Updated Service1:
public class Service1: IService1
{
private readonly HttpRequestMessage request;
private IDbSession dbSession;
public SampleService(HttpRequestMessage request)
{
// WARNING: Never attempt to access request.Properties[Constants.RequestProperty.DbSession]
// in the ctor, it won't be set yet.
this.request = request;
}
private IDbSession Db => (IDbSession)request.Properties["DbSession"];
public Foo GetFoo(int id)
{
return this.Db.Query<Foo>(...);
}
public Foo CreateFoo(Foo newFoo)
{
this.Db.Insert<Foo>(newFoo);
return newFoo;
}
}
I assume I will need to create an ActionFilter that will look for the indicator attribute and with that information identify, or create, the correct type of IDbSession (read-only or read-write).
With your current design, I would say an ActionFilter is the way to go. I do think however that a different design would serve you better, which is one where business operations are more explicitly modelled behind a generic abstraction, since you can in that case place the attribute in the business operation, and when you explicitly separate read operations from write operations (CQS/CQRS), you might not even need this attribute at all. But I'll consider this out of scope of your question right now, so that means an ActionFilter is the the way to go for you.
But how do I make sure that the created IDbSession's lifecycle is managed by the container?
The trick is let the ActionFilter store information about which database to use in a request-global value. This allows you to create a proxy implementation for IDbSession that is able to switch between a readable and writable implementation internally, based on this setting.
For instance:
public class ReadWriteSwitchableDbSessionProxy : IDbSession
{
private readonly IDbSession reader;
private readonly IDbSession writer;
public ReadWriteSwitchableDbSessionProxy(
IDbSession reader, IDbSession writer) { ... }
// Session operations
public IQueryable<T> Set<T>() => this.CurrentSession.Set<T>();
private IDbSession CurrentSession
{
get
{
var write = (bool)HttpContext.Current.Items["WritableSession"];
return write ? this.writer : this.reader;
}
}
}

Constructor injection best practices

I have 3 service components, one low-level service responsible for some kind of data serialization, one in the middle responsible for coordinating saves/loads, and one MVC Controller responsible for API publication.
Each of the 3 components logically refers to the other "below" it. The middle service has another parameter, which is known at runtime, based on request data. From this 3 components the controller and the middle service are represented by classes (doesn't make sense to introduce interfaces because nothing to mock), and the lowest level is repesented by an interface, making it available to unit-test the middle service or the controller. I'd like to use DI (specifically Ninject) to build my controller class. My question is if any kind of best practice exists for handling this scenario. Currently I see two way of implementation. (The validations, proper implementations are ommitted for the clarity.)
First of all, here is a sample implementation of the middle service and the lower level interface.
public interface ISerializer {
void Serialize(object data);
}
public class MyService {
private string _dataId;
private ISerializer _serializer;
public MyService(string dataId, ISerializer serializer) {
_serializer = serializer;
_dataId = dataId;
}
public bool CanProcess(MyDTO data) {
...
}
public void DoSomeProcessing(MyDTO data) {
...
}
}
Version 1: inject the whole middle service to the controller as a factory
public class MyController : Controller {
private Func<string, MyService> _myServiceFactory;
public MyController(Func<string, MyService> myServiceFactory) {
_myServiceFactory = myServiceFactory;
}
...
[HttpPost]
public JsonResult Process(string dataId, MyDTO model) {
using (var myService = _myServiceFactory(dataId)) {
...
if (myService.CanProcess(model))
myService.DoSomeProcessing(model);
...
return Json("ok");
}
}
}
Version 2: Injecting directly the lower-level interface to the controller, and instantiate the middle service "manually".
public class MyController : Controller {
private ISerializer _serializer;
public MyController(ISerializer serializer) {
_serializer = serializer;
}
...
[HttpPost]
public JsonResult Process(string dataId, MyDTO model) {
using (var myService = new MyService(dataId, _serializer) {
...
if (myService.CanProcess(model))
myService.DoSomeProcessing(model);
...
return Json("ok");
}
}
}
Which one is more proper, or should I choose a completely different solution?
First of all, I like my services to be stateless, so I don't like the idea of passing dataId
to the service's constructor. When services are stateless they are safer. You can call their methods not worrying if they are currently in a valid state. It also makes it easier to test and mock them. You can also reduce the amount of used memory, as you only need one instance of a stateless service.
If you moved dataId to DoSomeProcessing as a parameter you would be able to easily instantiate MyService with Ninject and the proper implementation of ISerializer would be injected automatically.
However if you insist on passing it to the constructor "Version 1" is quite close to what I'd consider good. Factory is a nice trick to let DI inject dependencies, when there are also data parameters needed in the constructor. I would inject MyServiceFactory to the controller. I'd create another class for it:
public class MyServiceFactory : IMyServiceFactory // an interface to me able to mock it if needed
{
ISerializer _serializer;
MyServiceFactory(ISerializer serializer){ // here Ninject can inject the dependency
_serializer = serializer;
}
IMyService Create(int dataId){ // here you can pass additional parameter
return new MyService(dataId, _serializer);
}
}
This way you can easily avoid hard dependencies and make the code more maintainable and more testable.
"Version 2" is wrong. If you ever want to test your controller or replace MyService with another implementation - you are stuck. You'll have to do a lot of tedious refactoring (depending on the amount of usages). And finally you'll end up with something similar to what I suggested above. :)

dependency injection alternatives

I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
The problem is that I don't want to write
BusinessProducts bp = new BusinessProducts(dataContextImplementation);
I would continue to write
BusinessProducts bp = new BusinessProducts();
because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.
Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?
I am coding in c# but alternatives from other languages is welcome
I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.
So my business products class would look like:
public class BusinessProducts
{
private IDataContextFactory DataContextFactory { get; set; } // my interface
public BusinessProducts() : this(null) {}
public BusinessProducts( IDataContextFactory factory )
{
this.DataContext = factory ?? new BusinessProductsDataContextFactory();
}
public void DoSomething()
{
using (DataContext dc = this.DataContextFactory().CreateDataContext())
{
...
}
}
An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.
You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.
I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = new SolidDataContext();
}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
}
This way you can use DI for overriding the default instance in unit testing testing.
Your feelings, while valid, are misplaced.
The Dependency Injection pattern is a direct application of the Inversion of Control principle.
This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.
As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.
There are two distinct cases here:
In production code you will never write
new BusinessProducts(dataContextImplementation)
because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.
In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.
http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.
Generally the framework itself will have the logic to build up the entire object tree. For example, instead of
new SomeObjectO(diContext)
you would call the framework like this:
DIFramework.GetNew<SomeObjectO>();
or
DIFramework.Get<SomeObject>();
Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.
If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.
BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();
If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.
There's a technique called poor man's DI that looks like this
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts() : this(new DataContext()) {}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to #tvanfosson but a lot simplier.
I second the recommendation for Windsor
My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.
you can also look at windsor for IoC .

Categories

Resources