1

Injecting dependencies in Global.asax does not seem to always work. Sometimes it does, sometimes I get a ContextDisposedException (it seems that the problem occurs when I'm doing a Page.Redirect ??). I'm in an ASP.NET WebForm context.

Here is my code:

public class Global : HttpApplication
{
    [Inject]
    public UserManager UserManager { get; set; }

    private void Application_PostAuthenticateRequest(object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated)
        {
            GlobalSecurityContext.SetPrincipal(User);

            string path = Request.AppRelativeCurrentExecutionFilePath;
            if (path.Contains(".aspx"))
            {
                // Get the current user
                var userData = UserManager.GetByIdWithLogin(User.Identity.Name);
                if (userData != null)
                {
                    LoginDataDTO data = userData.LoginData; 
                    if (data.XXX && ...)
                    {
                        Response.Redirect(...);
                    }
                }
            }
        }
    }

    protected void Session_End(Object sender, EventArgs e)
    {
        UserManager.Logout();
    }
}

In this post How to inject dependencies into the global.asax.cs, Mark Seemann says that one should not use Dependency Injection in global.asax because global.asax IS the Composition Root.

So what is the best way to solve my problem since I don't want to directly call my UserManager because the constructor needs a repository

public UserManager(IGenericRepository repository) : base(repository)
{
}

and the GenericRepository has itself a constructor that needs a IContext

public GenericRepository(IContext context)
{
}

I could probably do new UserManager(new GenericRepository(new MyContext)) but

  1. I will not reuse the same context for the whole request
  2. I need to add a reference on my AccessLayer in the GUI, what I would like to avoid

Just as an information, currently I'm injecting the Context like this:

// Dynamically load the context so that we dont have a direct reference on it!
string contextType = // read type from web.config
if (!String.IsNullOrEmpty(contextType))
{
    Type context = Type.GetType(contextType);
    Bind<IContext>().To(context).InRequestScope();
}

Any help would be greatly appreciated !

[Edit]:

Changing the UserProperty property like this works:

public UserManager UserManager
{
    get { return ServiceLocator.Current.GetInstance<UserManager>(); }
}
Community
  • 1
  • 1
Bidou
  • 7,378
  • 9
  • 47
  • 70
  • 3
    I concur that the Global.asax is the entry point - the composition root. You wire up your dependencies there, so you can't *inject* anything. I'd just use `Resolve` method of your IoC container to get the instance you need. – Patryk Ćwiek May 29 '13 at 06:58
  • This is like asking, why can't I use the DI container before I created it :-P – Steven May 29 '13 at 07:36
  • Steven: The DI Container is created OnStart, so it should be available in my PostAuthenticate method, isn't it? And as I wrote, most of the time this code is working... it just fails sometimes. – Bidou May 29 '13 at 07:53
  • @Bidou 'Fails sometimes' is not a very good description. Give us an exception. And if you can't, then there's your problem - have a search for ELMAH etc. – Ruben Bartelink May 29 '13 at 07:58
  • Ruben: This is what I did... "Sometimes it does, sometimes I get a ContextDisposedException (it seems that the problem occurs when I'm doing a Page.Redirect ??)." – Bidou May 29 '13 at 08:07

1 Answers1

2

In this case you can build your Ninject container, and use it a Service Locator for this particular instance (since you're in the Composition Root - you can't inject anything at this point).

Dimitar Dimitrov
  • 14,868
  • 8
  • 51
  • 79