This project is read-only.

Changing dependency implementation based on active module

Topics: Writing modules
Jan 16, 2012 at 1:31 PM
Edited Jan 24, 2012 at 9:26 AM

(Sorry I couldn't find a better title.)

My project has the following structure:

  • BaseModule
    • HomeController, taking dependency on BaseDependency
    • IBaseDependency : IDependenc (interface)
    • BaseDependency : IBaseDependency (implementation)
  • TopModuleA
    • Routes.cs routing TopModuleA/Home to BaseModule/Home
    • ITopDependencyA : IBaseDependency
    • TopDependencyA : BaseDependency, ITopDependencyA
    • Dependencies: BaseModule in Module.txt
  • TopModuleB
    • Routes.cs routing TopModuleB/Home to BaseModule/Home
    • ITopDependencyB : IBaseDependency
    • TopDependencyB : BaseDependenc, ITopDependencyB
    • Dependencies: BaseModule in Module.txt

I'd like to the following to happen:

  • On TopModuleA/Home BaseModule/HomeController gets called with TopDependencyA injected
  • On TopModuleB/Home BaseModule/HomeController gets called with TopDependencyB injected

So basically I'd like to change which BaseDependency gets injected into HomeController based on whether TopModuleA or TopModuleB is "active". I thought the above would simply work but it doesn't and I'm quite clueless how it could. Anybody has an idea?

Maybe the problem is that the order in which dependencies are resolved is depending on in which order they're registered (after figuring out module dependencies). Since registration happens on shell start, TopModuleB's TopDependencyB will get registered last, so it "wins" every time.

Thank you for everyone who makes time to read my question.

Jan 16, 2012 at 2:43 PM

Yup, dependencies are shell-wide and which injections you get is irrespective of which module is getting routed.

I'm creating this crazy little module called "Alchemy" which will be perfect for creating flexible, pluggable routes like this ... but it's not exactly production code yet.

The best thing you can do here is have a single controller which accepts a string parameter, and pass that parameter in your route. Then look up in a list of dependencies for anything matching that string key to find the correct dependency for that route. (This is essentially what Alchemy is doing, but in a vastly generalised form, with a ridiculous amount of pluggability).

Jan 16, 2012 at 4:34 PM
Edited Jan 16, 2012 at 4:36 PM

Thanks, that's what I feared. The solution I came up with is the following:

Pass a parameter in the Route's dataTokens indicating upon which module the controller is executing (fortunately there was already a RoutesBase to handle the common tasks), then...

  • Check this dataToken in HomeController's Initialize() method
  • Or check this dataToken in an IActionFilter

and then load the appropriate BaseDependency depending on the content of the dataToken (fortunately a locator to do this was also already written). It gets a bit more complex as the BaseDependency instance should be injected into a number of other services as well that are required by HomeController, so either...

  • All the services should be lazy-loaded and before the earliest load the implementation of BaseDependency should be changed in Autofac
  • Or the implementation stored inside the already loaded services should be swapped to the one located depending on the dataToken.

I'm still wondering what the best approach would be, but I think the nicest way would be to change the registered implementation in Autofac before HomeController gets instantiated, but I haven't found a way to do it and I begin to doubt whether there's any way to do this in ASP.NET MVC without a custom controller factory (or modifying Global.asax, which is not really an option here).

P.S.: Your modules' names are cool :-).

Jan 16, 2012 at 5:07 PM

I think trying to coax Autofac into giving you the right dependency at the right time might be a convoluted and problematic way to implement what you're after, and to me it sounds like it could be slightly contrary to the principles of dependency injection (of course, I don't know exactly what you're trying to achieve).

Let's start with the facts: you have an identifier key, which is a simple string. This is available in your controller action (you don't need a filter or anything special, it can just be an ordinary parameter of your action method).

You then require various behaviours to change depending on the value of this key. Instead of trying to "cheat" dependency injection to get the different behaviours, why not just have your various dependencies expose a GetIdentifier() method. Then any time you need one, you can just enumerate an IEnumerable<IMyDependency> to check for the one that matches the identifier on the current request. Obviously the methods on any services or whatever you might have will also need a parameter to pass in this identifier, so they themselves can look up the correct dependency.

It might be a little more work doing things this way, but you won't have to do any custom manipulation of Autofac, and it'll leave you the most flexibility in how you (or others) reused those services or dependencies in other places.

A lot of existing modules do very much the same thing, off the top of my head the Forms module uses a string key for the form name. In fact, each form handler runs, and it's up to that handler to decide whether or not to participate, based on the current form key. This is really the principle of dependency injection when you're dealing with multiple behaviours (rather than single services); you shouldn't be telling the system which one to run, just let them all run and they can choose whether or not to modify a context object that you pass in.

Hope that makes sense; I can elaborate with further examples if needed!

Piedone wrote:

P.S.: Your modules' names are cool :-).

Thanks - some people just find them confusing ;) I spend probably too much time figuring them out. Actually, "Alchemy" is one I wanted to have for quite a while, but I only just worked out the functionality to go in it. Almost a case of the name driving the feature ... But there's an underlying pattern. These are all "Science Project" modules, so each module is named after some distinct branch of scientific or at least academic thinking; Mechanics, Cartography, Origami (the science of shape folding...)

Jan 16, 2012 at 6:25 PM

Very valid points, thanks again for you insightful help! I think what I'm trying to achieve does make sense here:

Imagine the HomeController here as something that outputs information about a BaseDependency instance. Now it can output this about any registered instance, but only about one at a time. That means, there can be an arbitrary number of BaseDependencies floating around in Autofac and I'd like to choose one and use it in the controller. So I think the principles of DI are not violated here; this use case here is like a plugin system were plugins are auto-discovered but you have to choose one to use at a time (but there is no assumption made about the plugins, i.e. there is no hard-coded plugin list, really there could be arbitrary plugins).

The way I'm trying to achieve the above goal might be awkward, but the principle is much like the one with IHtmlFilters (I haven't looked into Forms, but from your description filters work quite the same). (This is going a bit away from the original question and will be a bit philosophical :-); it also adds information about the objects I use here, that are superfluous to the question.) The difference is, that not all registered BaseDependencies are run and they decide whether they should run or not but rather all BaseDependencies expose information what they're capable of doing and the consuming part decides which one to run. This is really what you described in the paragraph "You then require various behaviours...": to be honest, the registered objects have an identifier (used by the specific case described in the question) and also "capabilities" for the previously mentioned scenario.

Actually after re-reading your post I see that not this was what bothered you with my proposed solution (so just treat the previous paragraphs as general ideas) but the way I wanted to trick Autofac. Yeah, it's not a nice approach; the thing is, if I'd like to create a kind of scope for the controller (I know scopes are possible with Autofac but I really can't apply them to this scenario as I don't know how I could let some code run just before controller instantiation), so all the action happening in it doesn't have to think about choosing the right dependency corresponding to the identifier. So the purpose of having the "choosing algorithm" at the point happening the earliest in the page life cycle possible is to keep all the underlying services or even the used constructor as simple as possible. Just as a side note, but these services can be used independently too with arbitrary BaseDependency implementations, that are changeable also between two method calls.

Hope that makes sense...

I've taken a look at Alchemy, still trying to understand it :-).

Jan 16, 2012 at 7:07 PM

This really does sound like exactly the set of problems I've tried to generalise with Alchemy. If you haven't seen it I wrote an overview and some basic examples here:

In a nutshell it's an idea I'm calling "Factory Injection". It has a specific concept of "Scope" (otherwise called "Context", or "Input") which consists of any number of types or string/object pairs you like. Alchemy factories can be described with statements of the following form:

"Given [scope] the method to produce [type] is [func]"

A process is broken down into a chain of object factories. Any of those factories can then be swapped out for different implementations, based on the scope. The idea is to break the process into as small individual factory units as possible, so later on you can swap out any piece of the chain you like. So it's like injecting individual statements into a method, rather than injecting or overriding entire classes as with normal dependency injection.

Regarding your original problem:

Yes it's a bit like IHtmlFilter, and some other dependencies in Orchard. I'll just quote the method signature of IHtmlFilter:

    public interface IHtmlFilter : IDependency {
        string ProcessContent(string text, string flavor);

And here's some code that uses it:

    var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text, GetFlavor(part)));

And here's an example IHtmlFilter implementation:

    public class MarkdownFilter : IHtmlFilter {
        public string ProcessContent(string text, string flavor) {
            return flavor.Equals("markdown", StringComparison.OrdinalIgnoreCase) ? MarkdownReplace(text) : text;

        private static string MarkdownReplace(string text) {
            if (string.IsNullOrEmpty(text))
                return string.Empty;

            var markdown = new MarkdownSharp.Markdown();
            return markdown.Transform(text);

(I realise you've probably seen all this, but I'm just quoting for clarity).

Now there's nothing especially complex here, the underlying services and constructors are very simple. All that happens is a string comparison to see if the flavor is correct before the IHtmlFilter runs. The BodyPart runs all IHtmlFilters but any that don't apply will just return the unmodified text, however multiple IHtmlFilters are still allowed to participate.

Let me just reiterate what DI is about: the caller should know nothing about the implementations that it's calling. The trick is to expose interfaces in such a way that you can blindly call whatever implementations are available; and it's up to those implementations to do the right thing with the data you make available to them (or other data they may acquire themselves through other dependencies, which again you can make no assumptions about). By pre-selecting a particular dependency you are already assuming some knowledge about which of those dependencies might apply.

Quick example: what if someone wanted to implement a BaseDependency to handle multiple routes? With the IHtmlFilter it's easy, you can check for multiple flavors, or even catch all of them (which the BBCodeFilter actually does).

Of course this is all pretty much abstract and philosophical because I still know nothing about the specific problem you're trying to solve, but by trying to inject in a different way for what seems to be a very small saving in code you could well be boxing yourself into a corner ;)  (And yes, reading that statement back it sounds somewhat hypocritical, because I've already been discussing my own way of reinventing injection!)

Jan 17, 2012 at 1:13 PM

Thanks again for the well thought-through input!

To concretize a bit (I'm not pretending the software I'm developing is a secret - although it's not ready for publishing yet -, but it's fairly complex and I try to omit details not needed), BaseDependency is a kind of setup, configuration or descriptor (or even context) object, meaning it stores information about how HomeController (or the services used by it; or generally any service in this system) should work. This "information" includes strings like identifiers or content type names but also non-primitive types like other objects or methods (therefore it's not possible to store the data they're carrying simply in the DB). So basically what happens here is just that I'd like to set the current context for the controller.

Now this indeed sounds much like part of what Alchemy does, as far as I know.

Thinking further a bit now I think what I really need is to be able to choose the interface of the IBaseDependency (edited the original question a bit) derivatives to inject into the controller (or any other services). This would of course narrow down injectable dependencies (meaning, now HomeController would request e.g. an ITopDependencyA in the constructor), but these would still be changeable by registering another ITopDependencyA implementation. Just thinking aloud...

I've also seen that the controller in Alchemy (more precisely, DisplayController's Index() method) acts like a kind of dispatcher if I understand correctly. This is what I tried to achieve in a different was previously (meaning there's a dispatcher controller that gets called to set the context for HomeController, than hands the control over to HomeController), but it was awkward, a bit slow and I couldn't get theming work properly. Maybe I should look into dynamic proxies used also in Orchard.

Jan 17, 2012 at 2:54 PM
Edited Jan 17, 2012 at 2:56 PM

You could definitely use Alchemy for this, although I still maintain as far as the information you've given here goes you can achieve all of this with straight dependencies, nothing special. It's no different to how loads of Orchard's modules already work; especially some of the newer bits like Projections, Rules, Tokens, and Forms (and I've based my newer modules - mainly Autoroute and Alchemy, but also some other currently secret things - on very similar principles).

How these modules all work is that a Describe context is initially generated by the service, and all the available dependencies populate the describe object with their supported behaviours and other parameters. Note that at this point no "input" or "scope" is available; the handlers are just describing what they are capable of (and what scope(s) they support). Also note that no DB access is performed during description, in fact very little work is performed at all, so this stage is very quick, they are just populating some lists and dictionaries with strings, delegates, etc.

Now the service wants to perform a task. So it looks through the description context it has built, finds any items matching the scope which is now available, and executes the delegates or performs other operations as appropriate.

To my mind this exactly matches what you require: "BaseDependency is a kind of setup, configuration or descriptor (or even context) object, meaning it stores information about how HomeController (or the services used by it; or generally any service in this system) should work. This "information" includes strings like identifiers or content type names but also non-primitive types like other objects or methods (therefore it's not possible to store the data they're carrying simply in the DB)."

All you need is a central service to function as the switch box (dispatcher), which your controller or any of your other services can call into to get the correct behaviour.

In the cases of all the modules I just mentioned, the service is acting as a dispatcher. Even in Alchemy; the dispatching isn't performed from the controller, it's performed by the IAlchemyService. The controller is simply invoking a call to the service, providing inputs, and handling the output.

You might want to look in detail through the code and interfaces for Rules and Tokens, they're in my opinion the cleanest and simplest examples of this kind of describe / dispatch behaviour, all using perfectly normal dependencies (usually an IEventHandler because this means you can often utilise the message bus instead of having a hard project reference).

Jan 24, 2012 at 9:47 AM

Thanks for all your help!

The solution I ended up after iterating over two other is pretty much the one you advised in your first answer. (The description following is again abstracted and simplified, but I hope it shows the point).

So the configuration/provider/descriptor objects, auto-discovered as dependencies (IBaseDependency implementations, from the original question) have public properties, storing among others the meta data that describes which HomeController they support (as they can also be more HomeControllers):

  • string SupportedController
  • int ConfigValue
  • string ConfigValue2
  • object ConfigValue3

Downside is that if there's a need for a new config value the interface has to change.

There's a service that gets the lastly registered provider for a controller with something along the lines of ProviderService.FindProvider(string controller).

I evaluated also two other approaches:

A simplified version of e.g. how Tokens work:

The provider only has a Describe(ProviderDescriptor descriptor) method. The ProviderDescriptor object is a blank object that the code inside Describe can fill up with the values mentioned above. Now this approach is nice, simple and flexible but I really disliked the idea that the ProviderDescriptor object's properties all should have public setters or a method that lets you overwrite its content. I wanted these descriptors to be practically immutable once set up.

The approach of Tokens:

It has all the flexibility of the previous but I felt that in my case the result became bloated.

Also there's a problem with the last two approaches: there's also a need for custom config values for the different controllers, e.g. one controller would need a long ConfigValue4 too (these values are arbitrary so there's no possibility to store them in a common datatype without constantly casting to and from object). The most straightforward way of achieving that the controllers can fetch a provider with their own custom type (which is a derivation of the common one) from the same service (so without a need to write too much custom code for every controller) was with the first solution. This way a generic service method cuts it:

ProviderService.FindProvider<TProvider>(string controller)

This returns the lastly registered provider that's assignable to TProvider.

I hope the above compilation will also help someone decide which is the best approach for them when in a similar situation.