Type 6 IOC, weaving the dependency 16 Dec 2004



Everybody's gone weavin',
Weavin' D.N.G. !

Life is a beach, let's try a new meta aspect : ReplaceConstructorCall, and by the way, discover a new type of IOC, not constructor based, not setter based, everything is done by AspectDNG. Maybe this is not even IOC. Don't care, it's cool.

I've written this today, it's some kind of proof of concept. It is in CVS now, but maybe it will evolve or change. IOC is one buzz word of today. In one of his (famous) article, in French, and in English, Sami Jaber describes 3 types of commonly used IOC, interface based, getter based, and constructor based. I have named this blog entry after this article on tss. Mainly because I'm not really serious. However, I think that AOP may "eclipse" IOC.
An example is coming.

The beginning, a very simple set of base classes :

// base.cs
namespace AspectDNG.Sample {

    public interface IComplexSystem {
        void DoTheWholeThing(string a);
    }
    
    public class MockSystem : IComplexSystem {
        public MockSystem() {}
        public void DoTheWholeThing(string a) {}
    }

    public class Pono {
        
        private string m_a;
        private IComplexSystem m_system = new MockSystem();
            
        public Pono(string a) {
            m_a = a;
        }
        
        public void TryTheThing() {
            m_system.DoTheWholeThing(m_a);
        }
    }
    
    public class EntryPoint {
        
        public static void Main(string[] args) {
            Pono p = new Pono("HELLO IOC6 !");
            p.TryTheThing();
        }
    }
}

What can we see there ? An interface, describing a complex system we want to use, then a Mock object, that may be avoided, but that is there for type safety, and for bookmarking. After this you find a plain old .net object, that depends on our complex system. The entry point creates the Pono object, and ask him to call its dependency. If you compile that and call it, nothing will happens. Let's weave the dependencies ! Here is my aspect :

// aspect.cs
namespace AspectDNG.Sample {
    
    using AspectDNG;
    
    [Insert("module:")]
    public class RealComplexSystem : IComplexSystem {
        
        [ReplaceConstructorCall("* *.MockSystem::.ctor()")]
        public RealComplexSystem() {}
        
        public void DoTheWholeThing(string a) {
            System.Console.WriteLine(a.ToLower());
        }
    }
}
This is a concrete implementation of my complex service. I use custom attributes to describe that I want RealComplexSystem to be inserted in the main module of the target assembly, and I use my new ReplaceConstructorCall. It's explicit, every call to the constructor of MockSystem will be replaced by the constructor of RealComplexSystem. It rocks no ?

If I execute this, my complex system will do its job :
D:/temporary/adng>AspectDNG -dw base.exe aspect.dll
D:/temporary/adng>base
hello ioc6 !
D:/temporary/adng>

So, what do you think about this ?