Dependency Injection is Dead!


Long live “Dependency Resolution”!


OK, so I’m not really serious – but I got your attention right? Truth is, I personally love Dependency Injection, but that doesn’t mean it isn’t without its flaws. The Service Locator pattern is often touted as Dependency Injection’s nearest rival, so let’s very briefly examine some of the characteristics of each of these to see what works and what doesn’t.


What is great about these patterns?


It is hard to condense my enthusiasm into just a few bullet points! I’m also sure I’ve missed some, but just to get our minds in sync;


1.       Testability; the loose coupling of your implementations means you can easily substitute mock classes, enabling your tests to focus on a single “unit”. You can also supply different implementations to allow testing at all (e.g. replace the calls to HttpContext.Current when you have no HttpContext).


2.       Design approach; enforcing loose coupling helps to encourage good design. It helps to shield consumers from the service’s implementation, enabling you to swap implementation if necessary.


3.       Configuration; there is often a big push towards highly configurable containers, both from the point of view of behaviour and their contents. This gives systems a feeling of agility, and the ability to adapt to different deployments or reuse in future systems.


4.       Object lifetime management flexibility; objects can be cached, be a singleton, or be short lived – all controlled through configuration.


What is wrong with Dependency Injection?


There are some potentially painful issues with DI;


1.       I find it counter intuitive that often some object somewhere needs to remember to “Build Up” an object. In other words, the chain of iterating over objects to fulfil their dependencies needs to start somewhere. This can be abstracted into HttpModules, framework code, and so on, but I still don’t like this. An object’s consumer shouldn’t need to know that X must be done before Y will work if at all possible.


2.       When using property injection you generally need to mark your dependencies as public. This can seem counter intuitive, and certainly limits some use cases. Constructor injection can help here though.


3.       Reflection; most (perhaps all?) Dependency Injection containers rely on some extent on Reflection – dynamically inspecting objects and determining their dependencies. I know there are optimisations out there for this, but the fact still remains that this can be an overhead.


4.       Object chains can become quite large. If they’re needed this is no problem, but what if they’re not? Consider this code;


public class Chain


{


    [CreateNew]


    public Customer PrimaryCustomer { get; set; }


    [CreateNew]


    public Partner Partner { get; set; }


    [CreateNew]


    public ProductCatalogue Catalogue { get; set; }


    [CreateNew]


    public AddressLookupService AddressLookup { get; set; }


 


    public string GetPrimaryCustomerName()


    {


        return PrimaryCustomer.Name;


    }


}


 


public class SecurityService


{


    [CreateNew]


    public LoginProvider Login { get; set; }


    [CreateNew]


    public RoleProvider Role { get; set; }


    [CreateNew]


    public TraceProvider Trace { get; set; }


    [CreateNew]


    public AuditService Audit { get; set; }


}


OK, so it isn’t meant to be nice code, so please don’t flame me J. Still, you see the point? If all I want to do is call GetPrimaryCustomerName, and all that uses is one single dependency, my container will still have created instances of all my other types and populated the dependencies of my Chain object… and of course done the same to all the dependent objects. This could quite easily lead to an increase 10-fold in needless object creation and initialisation! “Use a singleton” I hear you say – sure, if applicable. But why use a pattern that has an enormous design impact on my code purely to reduce object creation just because my DI container is doing something slightly crazy? And even if I’m not creating objects, I’m still resolving their references.


What is wrong with Service Locator?


My main bug-bear with Service Locator is that it permeates throughout all my code. And most importantly, every object I write must know about the Service Locator in order to be able to fetch its dependencies.


Consider the following code adapted from the example above;


public class Chain


{


    public string GetPrimaryCustomerName()


    {


        Customer primaryCustomer = ServiceContainer.Resolve<Customer>();


        return primaryCustomer.Name;


    }


}


This is must nicer – but it does mean my Chain class needs to know how to get hold of a Customer. Is this really so different to just creating a new one? Obviously you get the configurability of the Service Locator, but the separation of concerns is wrong in my opinion.


I should point out at this point that some clever people I know actually positively like this approach – they want to be explicit about fetching services and working with them. I see their point, and guess this comes down to personal preference, but the key is, if you like this approach chances are you don’t like DI at all – so this article is hopefully still of interest!


Lazy Dependency Resolution


So can’t we get the benefits of Dependency Injection and Service Locator without some of the drawbacks? I hope so; enter “Lazy Dependency Resolution” (which I already seem to keep abbreviating to just “Dependency Resolution”).


This is actually nothing new; I’ve just given it a name that sounds appropriate, having found a use for a new framework I’ve been playing with. Really, this is an approach cobbled together from various ideas and sources, and some similar ideas flying around “out there” on the web, but then that’s where all the best patterns start I think!


With the advent of static weavers that allow us to intercept calls using Aspect Oriented Programming techniques (see my previous article), we suddenly have an opportunity. The fact of the matter is that the Service Locator pattern does pretty much everything your average DI framework does, except that the service consumer needs some knowledge about how to call the Service Locator. Well, if we pull that concept out of our consumer classes and stuff it into a shiny new Aspect, what do you get? I think you get an implementation of a “Lazy Service Locator” that isn’t tightly coupled into the service consumer.


Enough talk, show me the code!


An Example with PostSharp


I’ve chosen to use PostSharp here as I’ve been playing with it a bit recently, but the idea is based on the concept of static weavers in general. If you want to know why this matters, read my previous article! </shameless-plug>


Quick Disclaimer: Note that this sample is really really rough-and-ready. It is not meant to be neat and tidy – it is just showing an alternative approach that I like. The reality is that I think some of the AOP libraries could help a bit by providing alternative interception models, support for explicitly only targeting properties a little more easily, or better ways of manipulating arguments and return values.


Anyway, for the simple demo we need two classes that must be loosely coupled; a consumer and a provider. The consumer consumes the provider… so to keep this dependency nice and flexible we’ll use an interface for our provider (so we could mock it if we liked, or switch implementations, etc).


public interface IProvider


{


    void PrintId();


}


I told you this was going to be a simple example J


Next we need a consumer class that makes a call to an IProvider implementation;


public class Consumer


{


    public IProvider Provider { get; set; }


 


    public void DisplayInfo()


    {


        Provider.PrintId();


    }


}


As you can see, we simply declare that we need an IProvider using a property here; we don’t specify where we get this from, or what concrete implementation we’re using. This matches how many Dependency Injection frameworks string objects together. Next, let’s have a concrete IProvider implementation (although we could have many different implementations if we liked);


public class ConcreteProvider : IProvider


{


    private Guid _id = Guid.NewGuid();


 


    public void PrintId()


    {


        Console.WriteLine(String.Format(“My ID is {0}.”, _id));


    }


}


So what I want to be able to do now is call my Consumer class in a completely transparent way, avoiding calls to build the object up, or fetch it from a factory, etc;


public class Program


{


    static void Main(string[] args)


    {


        Consumer consumer = new Consumer();


        consumer.DisplayInfo();


    }


}


OK, build it, run it… oh wait, we got a NullReferenceException because the Provider property is null.


Somehow, then, we want to tell our Consumer class which IProvider implementation it should be using. Well consider the following Aspect code;


[Serializable]


public class DependencyResolutionAspect : OnMethodInvocationAspect


{


    public override void OnInvocation(MethodInvocationEventArgs eventArgs)


    {


        eventArgs.ReturnValue = ServiceContainer.Resolve(


                eventArgs.Delegate.Method.ReturnType);


    }


}


What this is doing is inspecting the declared return type of the method call we’re currently intercepting, and then looking up an implementation in a Service Container to return to the caller. This Service Container could be a facade to any number of registry techniques, so I’ve not included the code. Of course, this means it might return a singleton instance, a new instance, a mock, a concrete live implementation – all the configurability of Dependency Injection or Service Locator remains.


We then simply apply this aspect to our Consumer class’ properties using an assembly-level attribute;


[assembly: DependencyResolutionAspect(


        AttributeTargetTypes=“PostSharpDR.Consumer”,


        AttributeTargetMembers=“get_*”)]


Of course, there are other ways to apply aspects, but this seemed the quickest and simplest sample. Note that I’m filtering for methods that begin with “get_”, which is how .NET compiles the “getter” for a property.


This now means my application code can run as we wanted – assuming the Service Container is suitably initialised. I’ve chosen to do this in code here, but of course this could easily come from configuration;


public class Program


{


    static void Main(string[] args)


    {


        ServiceContainer.Register<IProvider>(new ConcreteProvider());


       


        Consumer consumer = new Consumer();


        consumer.DisplayInfo();


    }


}


As if by magic, our application now works.


One unpleasant implementation detail is that we effectively have a property that does nothing on our Consumer class. In fact, code that assigns to this property will compile, but is counter-intuitive at run time as the value you pass in will never be passed out again from the getter! Therefore, consider the following aspect instead;


[Serializable]


public class DependencyResolutionAspect : OnMethodInvocationAspect


{


    public override void OnInvocation(MethodInvocationEventArgs eventArgs)


    {


        object existingImplementation =


                eventArgs.Delegate.DynamicInvoke(


                        eventArgs.GetArgumentArray());


 


        if (existingImplementation != null)


            eventArgs.ReturnValue = existingImplementation;


        else


            eventArgs.ReturnValue = ServiceContainer.Resolve(


                eventArgs.Delegate.Method.ReturnType);


    }


}


* Note this doesn’t support value types correctly! Again, I’m trying to keep my code simple


Now our aspect will invoke the property that it is intercepting, and return the property’s existing value if it is non-null. If the current value of the property is null, we return an implementation resolved via our Service Container. Of course we could do this in a number of ways (e.g. intercept the set call too, and use a private Boolean field that flags whether a manual set has occurred). This now means we can override the Dependency Resolution behaviour – something that could be really useful for testing if we don’t think we need (or want) to spin up a configured Service Container.


Therefore the following code in a unit test will always use our MockProvider, without changing how any aspects are compiled, and without worrying about whether a Service Container has been initialised or not.


Consumer consumer = new Consumer();


consumer.Provider = new MockProvider();


consumer.DisplayInfo();


Simple huh? The last thing I should mention is that caching the resolved service would probably be worthwhile – because at the moment we’re calling to the service container on every access to the property. This is easy to fix though, so I haven’t bothered for the sake of this post J


Good, Bad, or Ugly?


I think the best way to consider how this stacks up against the alternatives is to compare against what I see as the down-sides to DI and Service Locator;


1.       Responsibility for building up objects. This responsibility has now been pulled out into an Aspect; ideal for AOP, this is a cross-cutting behaviour that I can apply to many methods using configuration statements. My code stays clean, my concerns are separated, and my developers, testers, and architects are all happy (oh, and the flying pigs are too).


2.       Public dependencies. I don’t see any reason why I couldn’t modify the IL for protected and private properties too. We’d just need to be a little careful of this – is a developer really expecting a private object to be resolved by an apparently “external” component? Oh, and I don’t support constructor injection in this post, but I’m sure we could.


3.       Reflection; Doh!! See comments below.


4.       Large object chains; This is perhaps the best bit; as all resolution is done in a “lazy” fashion, only those paths through the object chain get created or resolved. Hey presto, no over-the-top object instantiation, yet no loss of benefits from a Dependency Injection style approach.


 


What don’t I like?


One issue is that really this needs a static weaver to achieve our aims – so many frameworks (Spring, the Enterprise Library, and so on) are out of the picture… for now.


[Edit: The following paragraph is my original content, but it turns out is not a completely accurate picture; be sure to check out Gael’s comments below – approx the 27th comment down! Simon] 


Secondly, the fact that my implementation using PostSharp still relies on reflection is a shame, and this is down to how the framework functions; really I’d like to edge this out of the door to maximise the benefits of the pattern, but I don’t fancy writing my own IL parsing cleverness! I haven’t had time to flesh out my ideas around this yet, but if I ever do I’ll be sure to post them!


Conclusion


Well, what do you think? Let the debate begin! I think this is a very simple evolution of Dependency Injection that removes some of the common objections to it – and hence could increase the audience that benefit from what I consider a good pattern to encourage good software design.


Be aware I haven’t used this in a real implementation yet… I’m floating a concept for discussion, so feel free to chip in.


 

Comments (38)

  1. Srikar says:

    No matter how you slice it, end of the day it all comes down to one and the same. There will still be overhead.

  2. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  3. Simone says:

    That’s a nice approach… but not that "DI is dead" (as referred to in the DNK title)…

    This is still DI, just injected in a different way: instead of using a IoC container the dependency is injected via an AOP framework…

  4. Simon J Ince says:

    Srikar;

    Yup, you’re absolutely right. But writing any software is always about trade-offs of performance against speed of development, good design, features, number of developers, and so on… and I think in a good proportion of cases this is a trade-off worth making. Not every case though, granted!

    Simone;

    I wouldn’t deny that – excuse my sense of humour with the post title 🙂  I do think the approach is different enough to increase the appeal of DI though, and also different enough to warrant a slightly different name to clarify the implications.

  5. Cool post, Simon.

    Here are my thoughts:

    The biggest problem with Service Locator is not the service locator permeating code, but the dependency upon global state (the state of the service locator.)

    Components that depend on a service locator, whether explicitly or through weaving, aren’t fully isolated from their environment. Controlling (and predicting) their behaviour depends on the behaviour of the global service locator.

    The dependencies of components using DI, on the other hand, can be controlled entirely at the point of instantiation.

    Most of the time the responsibility for this lies with the container, but creating and configuring a component outside of the container will always work predictably. This increases the flexibility of the system – it is easy to put existing components to work in new ways.

    Regarding:

    >>An object’s consumer shouldn’t need to know that X must be done before Y will work if at all possible.

    I think perhaps the inverse is true – it is better to manage complexity up front than to have it build up behind the scenes. The important thing here is how the API of the component communicates its dependencies. E.g. if X must be done before Y, the X must be done via the constructor.

    I think the approach you’ve described could be a successful improvement on Service Locator, but it doesn’t provide the flexibility or the complexity management you’d get with Dependency Injection. Keen to see where it goes though, I’m sure many more people will want to add their (differing) thoughts on the matter 🙂

    BTW, several containers – especially http://autofac.org – can use delegates to instantiate components, eliminating the need for reflection, if you like.

    Thanks for the really thoughtful post, looking forwards to reading more!

    Nick

  6. Casper Bang says:

    Very good post Simon. Personally I am no huge fan of DI as it’s hyped as a magic bullet these days – funny enough also by people who do not know about SPI’s (the service provider pattern).

    I’ve used SPI’s for years and it assists both in mockup and component-decoupling scenarios. And frankly I like not having to add another framework to the stack.

    As to your issue with service provider, you can simply use a static factory method to hide the lookup part. In fact, if you did this up front (as you’re suppose to purists will claim) it’s trivial to extend it to be a true SPI without any consequence to existing code.

  7. Nate Kohari says:

    Interesting idea, but as you say yourself:

    "As if by magic, our application now works."

    The danger here is that it won’t be clear to other developers where the values are coming from. This is a problem with AOP in general — by relying on post-weaving you give up the declarative nature of your code.

    Also, relying on AOP to inject dependencies will cause maintenance nightmares down the road. Further, I’d argue that this solution doesn’t provide the same sort of features a typical DI framework gives you — things like lifecycle management and more complex type resolution scenarios.

    If you’re concerned about reflection, a couple of DI frameworks provide ways around it: <a href="http://ninject.org/">Ninject</a&gt; (my framework) uses DynamicMethod to generate delegates that do the injection, and as Nick said above, his autofac framework is entirely geared around delegates.

  8. Nate Kohari says:

    @Casper:

    The service locator pattern forces you to couple all of your components to the locator. Also, if you want to alter the composition of your application, you have to change the calls to the service locator, meaning you’re forced to modify the implementations of your different components.

    The use of static methods in general make your code very inflexible, and the use of a service locator means that you will have static calls in nearly every component of your application.

    Dependency injection provides a non-invasive way to wire up components from the outside, and lets you collect this binding logic in a single deterministic location.

    Anyone hyping DI as a silver bullet is mistaken, but there are clear advantages versus the use of service locators.

  9. 1/ An object’s consumer shouldn’t need to know that X

    That is right, this is why you use an IoC.

    The one place that needs to know about the container is the infrastructure, everything else is constructed by the container.

    2/ When using property injection you generally need to mark your dependencies as public

    Use ctor injection, that is the preferred mode.

    3/ Reflection

    all IoC containers use a heavily optimized approaches, down to generating IL at runtime.

    I have not seen production ready container that had perf problems because of that.

    4/ Large object chains create lot of objects

    Who _cares_ ?

    It takes 0.00000006 ms to create an object in .NET

    This is absolutely insignificant number.

  10. Casper Bang says:

    @Nate:

    Thanks but correct me if I am wrong, doesn’t DI rely on a container to do the injection? If so, is that not as much a dependency as relying on an abstract service provider to do the mediation? At the end of the day, SOMETHING is going to have this binding knowledge.

    Perhaps I have not truly seen all the advantages of DI but some of the stuff I have seen which uses a lot of configuration and reflection is just not worth it, I happen to like it very much when I can do type-safe modeling within the IDE.

  11. Casey says:

    That looks much worse than even a service locator approach … the magic is even more hidden ….

    Be explicit … hiding stuff is not the objective …

    The same as an IoC container is not the answer to every scenario, AOP especially via weaving is definitely not …

  12. "I think some of the AOP libraries could help … by providing alternative interception models, support for explicitly only targeting properties …, or better ways of manipulating arguments and return values."

    I wholeheartedly agree.

  13. Jason Olson says:

    @Casper

    Casper, it is also about separation of concerns. Individual classes should not have to be concerned with DI, they don’t even care how it’s done.

    You can also think about it around the Single Responsibility Principle. When using a DI container, the sole responsibility of injecting dependencies lies with the container, not with any classes needing dependencies.

    However, when using a Service Locator, your classes now have to care (and have "expert knowledge") on where it gets its dependencies from. If you ever change the model of how dependencies are filled (let’s say changing the interface of the Service Locator itself), every single class in your application breaks (which definitely breaks the Open-Closed Principle). A static dependency in .NET is about as tight of coupling as you can possibly get. When using a DI container though, the DI container itself can change and won’t impact any of the classes.

    This is why I like the DI container approach versus the Service Locator. Classes don’t have to know about dependency injection, they’re single responsibility is to fulfill their desired behavior.

  14. logicalmind says:

    I use spring.net for my DI needs so I am a bit confused by some of the things in this article. A very simple setup would look like this:

    public interface IProvider { void DoSomething(); }

    class ProviderImpl : IProvider

    {

     public void DoSomething() { … }

    }

    public interface IConsumer { void Go(); }

    class ConsumerImpl : IConsumer

    {

     private IProvider provider;

     public IProvider Provider

     { set { provider = value; } }

     public void Go() { provider.DoSomething(); }

    }

    Note that my implementation classes are not public. Nobody knows what classes my implementation depend on. They simply know and use the interfaces. The dependencies are defined in the config file (uses property injection):

    <object id="Provider" type="ProviderImpl" />

    <object id="Consumer" type="ConsumerImpl">

     <properties name="Provider" ref="Provider"/>

    </object>

    A user of the consumer has the option of doing a manual lookup:

    var ctx = ContextRegistry.GetContext();

    var x = (IConsumer)ctx.GetObject("Consumer");

    Or putting a config in place to inject the dependencies.

    Also, it depends on your environment, but I don’t really care how many objects need to be injected into my classes. This is because my application is a long running web application. I take a small startup hit for the first instantiation but after that it goes away.

  15. I know that the title is meant to get attention but it is still wrong

    You are still doing DI.Even something like dependency = new SomeObject(); o = new MyObject(dependency) uses DI. What you are replacing is the IoC container approach…

  16. Daniel Jin says:

    If you use a service locator, I think this is a pretty good use of SoC through AOP. Although I am not exactly on board with this being a better alternative to DI with a container.

  17. Torkel says:

    I am also a little puzzled by your list of problems with Service Locator.

    "My main bug-bear with Service Locator is that it permeates throughout all my code. And most importantly, every object I write must know about the Service Locator in order to be able to fetch its dependencies."

    This is most definitely not true for the most common or "preferred" way to use IoC containers, that is the IoC container is only used by the infrastructure (HttpModule, ControllerFactory, etc).

  18. Simon J Ince says:

    Great comments everyone, thanks for the thoughts – and keep them coming. I fully admit I don’t have all the answers here – this is just a concept I’ve thrown out to see what the community thinks, so shout up 🙂

    Anyway, I’ll try and reply to some of the comments so far;

    Nicholas;

    True that classes that rely on this approach are not isolated from their environment *in compiled form* – although they are in source form (as this is the point of AOP). This works for me though – when they are compiled into a system I don’t need my code to be isolated. I guess this isn’t the case for framework authors etc though, so is a point worth considering.

    Regarding my comment about an object knowing X must be done before Y – you’re spot on. I think I explained this badly! My objection is when some other external component must be explicitly invoked to initialize an object. So I don’t generally like this;

    MyObject o = new MyObject();
    Configurator.ApplySettings(o);
    o.DoSomething();

    … but I do like this;

    MyObject o = new MyObject(myConfigurator);
    o.Initialize();
    o.DoSomething();

    Interesting comments on delegates; I’ll be sure to check out autofac.

    Nate & Casey;

    I hear your concerns about being explicit, but I don’t think it is a major issue;

    Firstly, I find that being consistent is more important than being explicit – as long as your application *always* resolves objects by doing X, and your documentation (both in code and in docs) states this (explicitly, I guess!!), your developers and support staff will be comfortable with the approach and know where to find things, and how they hang together.

    Secondly, you can use AOP in an explicit way – just move the [assembly:DependencyResolutionAspect] attribute to be on the property itself, rather than hidden away in AssemblyInfo.cs, and it is pretty clear to the developer that an aspect is applied. I just opted to keep it separate because so many DI people hate attribute-based DI 🙂

    Thirdly, and most importantly, surely putting all your object configuration in a config file and relying on a container somewhere to build up your objects (i.e. DI) is failing to be explicit too? I would see Service Locator as the most explicit approach, which is why I referred to “some clever people I know actually positively like this approach”… because they like to be explicit and use Service Locator all the time. Am I missing something here?

    You’re right though, Casey, trying to hide stuff would be bad!! I’m not aiming to hide implementation; I just want to simplify code so that the real meat of logic that needs to be built and maintained can be focused on without repetitive plumbing code.

    Nate;

    How do you believe AOP will lead to maintenance problems? I’d be really keen to hear your thoughts here as I believe the opposite; simplifying code and hence maintenance is one of my main drivers! Therefore if I’ve not seen an issue and you have, shout up 🙂

    Ayende;

    1. Surely this *is* IOC!! Just a different approach?

    4. Personally I agree for 99% of cases. Chances are a big database transaction is going to be your bottleneck (by a factor of thousands of times no doubt), not creating one extra object… but I do speak to many people that are cautious of DI – and I love it, so if at all possible I’d love to convince them to consider it… hence this post 🙂

    … so I still exercise a little caution because I don’t think it is fair to dismiss people’s concerns. There are still overheads involved, no matter how small I think they are. If the container is doing more complex configuration of objects it isn’t necessarily just a single “new” operation – actually when resolving a chain of 100 objects that might involve many other calls (e.g, 100 look-ups in a Dictionary, 100 calls to check XML configuration, 50 lock { } blocks, 50 object creations, and who knows what else!).  I’m sure you can put me straight on how Windsor works mind!

    Anyway, this doesn’t change the fact that I believe this to be a completely justified trade-off… but consider Dependency Resolution – all the above downsides hold true, except that due to the “lazy” way it works, one hundredth of this processing would happen if only one of the 100 dependencies were used! Of course, chances are all the clever optimisations that DI containers use could be applied to this too, to really make it fly. Can that be a bad thing? It is an alternative with all the benefits but adding some pretty standard good practices (i.e. a form of lazy loading) to tune the algorithm.

    Arnon;

    Good point 🙂   Although I think the terminology Dependency Injection has evolved to refer to more than that, I see what you’re saying!

    Torkel;

    Completely agree – but what you refer to is what I would call DI, not Service Locator. With a classic Service Locator, it is the responsibility of the consuming class to “go find the service”, and this is what I was referring to.

    Everyone;

    There seems to be a general consensus that DI can do something with clever object configurations etc that some kind of clever service locator can’t. Really? Anyone want to volunteer an example to prove it? I just can’t think of a scenario that this holds true for.

  19. Casper Bang says:

    @Jason

    Yeah well if you use a platform with build in support for the service provider pattern (java.util.ServiceLoader) the danger of being tied to this service is no bigger the way I see it, than being tied to a given build in type, say Decimal. You can only apply the open-closed principle so far.

    I can follow the reasoning for your preference in changing only annotation content rather than actual code, but you STILL need to make modifications, it’s just not in the source itself. But then you loose a lot of the reason why you are using a statically typed language to begin with. I.e. the ability for you to be able to read your code when taking a peek at a file in your SCM-system as well as counter your tools ability of to doing static analysis.

  20. Simon J Ince says:

    logicalmind;

    Your example is pretty much how I would use Spring too. The manual resolution approach that DI frameworks provide as well as the "injection" approach is just Service Locator.

    I think I’m going to have to quit with whinging about my comment number [2] ("when using property injection you generally need to mark your dependencies as public") and admit it isn’t really a significant problem… I already pointed out that constructor injection gets around this. I guess I’m just curious as to whether there is an opportunity to use some kind of DI/locator logic to wire up private implementations (i.e. swapping in/out strategies)… but this opens a whole new can of worms.

    Either way, you’re spot on – my concern is the public nature of the property (which is defined by an interface) not the class/implementation, as you rightly confirm, but this can be avoided.

    Hope that makes sense!

    Casper;

    You just reminded me of something many people don’t know exists in .NET; The IServiceProvider interface – http://msdn.microsoft.com/en-us/library/system.iserviceprovider(VS.80).aspx

    Very basic though 🙁

    Cheers everyone! Keep ’em coming, and shout up if I’m talking rubbish 🙂

    Simon

  21. I tried to write about the complexity that arises from using DI and IoC in a post here: http://kevin-berridge.blogspot.com/2008/06/ioc-and-di-complexity.html

    I like your ideas about applying AOP to the problem in an attempt to simplify code.  Overall I think that many of the draw backs of these types of architectures are still there.  And in some ways the "wiring" is even more magical, which does make it harder to understand how it works.

  22. Miguel Madero says:

    Simon,

    I’m not sure about how PostShar did this, but I thought it could help eliminate reflection doing that stuff at runtime.

    I tought Laos did some IL magic and somehow compiled the instructions to statically refer to the real stuff instead of goind to reflection.

    Mmm now that I write, altough it sounds possible, dont sound real… Anyway, I wanted to post this.

    I saw Gael read your post and didnt said anything about that.

  23. Simon J Ince says:

    Miguel;

    I agree – it would be great to avoid reflection, and I suspect there are ways this could be done. In fact, I have a nagging feeling that lamdas might help here… but I haven’t had time to prove it to myself.

    If you have a look at some code that has had aspects weaved in by PostSharp you should see the use of the methodof() statement. I’m curious why this can’t just be hard coded as "MyMethodName" for example, if you don’t need detailed runtime reflection information on the caller. I guess it would reduce the flexibility of the framework though.

    If there’s a good explanation out there Gael / anyone feel free link to it here…

    Simon

  24. gfraiteur says:

    I did post some comment, but it got lost.

    Anyway.

    I don’t see in the code where you use reflection, so hard to say how to not use it.

    Gael

  25. Miguel Madero says:

    There’s obviously less reflection, because we wont have the class inspecting all properties, constructor, etc looking for Attributes to do something, but there’s still a lot of reflection involved on setting a methods values, dynamically invoking them when needed or getting their return type. All this is using reflecting? or does it get somehow optimized on IL generation? It would still be less reflection than using a DIfx.

    I’m worried about that, specially since reflection is a big hit in the .NET Compact Framework space, and was thinking AOP could be of great help in reducing the amount of reflection needed (once PostSharp supports the CF).

  26. gfraiteur says:

    Reflection is not evil, because PostSharp is "just" a bigger reflection engine (with the ability to have random write access to it).

    What is evil is runtime reflection.

    There are many things we can do at compile-time (inside CompileTimeInitialize). We could inspect custom attributes and types there. But anyway the strength (and actually raison d’etre) of the IoC container is the ability to change bindings at runtime. So we cannot ask PostSharp to resolve dependencies at compile-time, it would not make sense. But we could already provide some analysis work.

    PostSharp for CF will not allow user code to be executed at compile time, so it fundamentally limits the set of features. There may be improvements in the future if there is a "market" for this.

    -Gael

  27. Simon J Ince says:

    @ Gael & Miguel,

    I was just typing a reply, and noticed something; I was referring to the reflection PostSharp uses in generated code – i.e. the methodof() operator…

    … but having just looked at my compiled example to get the precise details I noticed it isn’t using this at… in which case, I guess it was one of the other aspect types that I noticed this in while playing with PostSharp? Interesting as this would mean I need to retract the comment in my conclusion!

    Can you shed any light on my misunderstanding Gael?

    If we’re not using reflection here I’m a very happy bunny 🙂

    Simon

  28. gfraiteur says:

    PostSharp does not need runtime reflection. For most aspects, it gives the reflection element of the aspect target, but it is only for aspect code. If the aspect does not use this information, it is probable that future versions will not provide it.

    The OnMethodInvocationAspect does not provide explicitely the MethodInfo, because it provides a Delegate, and it is pretty easy to get the MethodInfo from the Delegate.

    Unfortunately, MS implementation of DynamicInvoke is pretty ugly (i.e. ineffective), because it uses reflection behind. I would be better to have to CLR generate this method dynamically, at it does for other delegate methods, but maybe it has not been identified as a key use case by the CLR team.

    Anyway, it is probable that future versions of PostSharp will use a more effective than DynamicInvoke. PostSharp could indeed generate the equivalent of this method, but in MSIL, so without reflection. It would be pretty faster… and compatible with Compact Framework and Silverlight.

    -Gael

  29. Simon J Ince says:

    Great – thanks for clearing that up Gael. I’ll edit the post above!

  30. Miguel Madero says:

    Gael,

    Does PostSharp 1.1 Beta 1 already has support for SL and CF?

  31. gfraiteur says:

    Actually yes, but it does not work well enough, so some heavy redesign is required. 1.1 is absolutely not supported yet.

  32. Miguel Madero says:

    I know its beta, but probably I’ll give it a try in the following weeks. I want to expand the concepts presented in this post to the CF.

    Thanks

  33. I am constantly surprised when speaking with people how few have heard of or use the “Service Interface”

  34. CF support has been released, btw.

  35. Steven says:

    If your worried about reflection, the Simple Service Locator dependency injection library (http://simpleservicelocator.codeplex.com/) doesn’t use any reflection at all. Plain old generics and delegates (and one interface under the covers).

  36. Simon J Ince says:

    @ Steven,

    Thanks for the comment.

    That project does look very interesting… but I would be careful to highlight that it is a "Service Locator" and *not* a Dependency Injector, which is why it’s so easy to avoid reflection, dynamic methods, etc.

    My solution above needs a Service Locator to function so I have actually have written my own simple locator that doesn’t do any of the more complex "building up" that DI containers would do automatically – i.e. something similar in concept to yours. I’m hoping to publish a whole functioning DR solution at some point so keep an eye out.

    Simon

  37. calebjenkins says:

    The one scenario where I think something like this could be a nice approach is in resource constraint platforms like Windows Phone. In almost any other scenario I would prefer the flexibility of a full DI/IoC Container… This is essentially creating "static" DI. I could see places where that would be nice.

  38. Simon J Ince says:

    @calebjenkins,

    I'm not sure I see how full DI is "more flexible". This isn't static – it is still driven by (configurable) service location in the background. That's the reason for my challenge in an early comment… read upwards for a while 🙂

    Totally agree that Phone 7 is a great target for this kind of thing though.

    Simon