This project is read-only.

Web Forms - How to load interface implementation from one of two assemblies depending on value of certain variable?

Jul 8, 2014 at 9:18 PM
I have two assemblies which implements the same interfaces. When user logs into web forms application certain variable (flag) is being set to specific value. This variable should be used for loading implementations from one of these assemblies. How could I implement this behavior? Please advise. Thanks.
Jul 8, 2014 at 9:21 PM
You could do something like this:
container.Register<ISomeAbstraction>(() =>
{
    IUserContext userContext = container.GetInstance<IUserContext>();
    return userContext.SomeFlag ? container.GetInstance<Implementation1>() : container.GetInstance<Implementation2>();
});
Jul 9, 2014 at 8:44 AM
That is something that is done in Global.asax, right? I can't do that because I need to wait for the user to login before I can decide from which assembly I need to load the implementation from?

Can I update the container from code behind of login.aspx page - how?
Can I override some method from SimpleInjector that instantiates implementations so that I can point to specific assembly based on a parameter I would put in session when user logs in?

Thanks.
Jul 9, 2014 at 9:21 AM
Can you explain a bit more about what you are trying to achieve. For instance, how are those assemblies referenced? Are they loaded as dynamic plugins, or are the referenced by your application project? Why can't you preload those assemblies?

Note that changing the container later on is not allowed, so everything you do must be done during startup of the application. But that doesn't mean you can't lazy load stuff. There are good solutions for this, but I need a more information from you find out what it is you really need.
Jul 9, 2014 at 9:32 AM
These two assemblies are two class libraries that are referenced by asp.net web forms application.

I can preload all these assemblies but that's confusing me a little bit since I would have:
    container.Register<IUserRepository, Assembly1.UserRepository>();
    container.Register<IUserRepository, Assembly2.UserRepository>();
Now, when a user logs in, I know which of these two implementations I need to use for that user: Assembly1.UserRepository or Assembly2.UserRepository and
I need to inject it in every page where I need to work with this (Index.aspx code behind, Market.aspx code behind ...). These two assemblies work with different databases. that's why I have this structure.

Can you help me with lazy loading - is that solution for this?

Thanks.
Jul 9, 2014 at 9:39 AM
I think my previous solution is still the way to go:
container.RegisterPerWebRequest<IUserContext, AspNetUserContext>();
container.Register<Assembly1.UserRepository>();
container.Register<Assembly2.UserRepository>();

container.Register<IUserRepository>(() =>
{
    IUserContext userContext = container.GetInstance<IUserContext>();

    return userContext.UseAssembly1
        ? container.GetInstance<Assembly1.UserRepository>() 
        : container.GetInstance<Assembly2.UserRepository>();
});
Marked as answer by dot_NET_Junkie on 8/11/2014 at 12:36 PM
Jul 9, 2014 at 1:14 PM
Thank you very much. Problem solved.