Humblecoder

Apprentice unit tester, expert rambler

Archive for the ‘OCInject’ tag

OCInject Release 2

with 2 comments

When I originally released OCInject I omitted one important feature, lifestyle management.  This coupled with the release of a feature full TinyIOC has made me re-evaluate my position on not adding too many features to OCInject.  Release 2 of OCinject brings the following features:

  • Life style management – It’s possible to register types as singletons or instance
  • Func<T> factories – OCInject from day one supported delegate factories, now you can use Func<TContract> instead of typed delegates
  • Simplified Registrations In the previous release of OCInject types are registered using TContract –> TImplemenation to enforce programming to interface.  It’s now possible to register with TContract as the concrete type with one call
  • Largest Resolvable ConstructorIn the previous release of OCInject it simply grabbed the first constructor it found.  It will now select the greediest constructor it can resolve.  It makes the assumption that any known types are resolvable, for performance reasons.
  • Unresolveable CallbackIt is now possible to supply a call back function if the container can’t resolve a type.
  • Child Container SupportOCInject can create child containers that call back to the parent for any unknown types. 

The latest stable version can be downloaded from Codeplex and all stableish development releases can be found at BitBucket.

Future Features

One major feature still missing from OCInject is named registrations.  This is because I personally dislike ‘magic strings’, with this in mind a planned future feature of OCInject is factory delegate registration only.  Also, auto generated factories from interfaces.  More to come on this in a future post.

Life Style Management

By default all types registered with the OCInject container are transient. You can register a type as singleton in two ways.  The first method is to use .AsSingleton() this will cause the object to be created the first time it is requested.  The second method is to use .AlwaysReturnObject(obj), this will return the instance you specified.   When using either method, if the type implements IDisposable it will be disposed when the container is.  Usage example:

ClassFactory container = new ClassFactory();

//Normal Singleton
container.RegisterType<TestClass>()
           .AsSingleton();

//Preconstructed Singleton
AnotherClass instanceOfAClass = new AnotherClass();

container.RegisterType<TestClass>()
         .AlwaysReturnObject(instanceOfAClass);

Func<T> Factories

When resolving constructors if OCInject discovers a Func<T> where T is a registered type, it will pass in a func to create the type.  This uses the standard container resolve, so if T is a singleton you will always get the same instance when the factory is called. Usage example:

class FuncConsumer
{
	public FuncConsumer(Func<TestClass> factory)
	{
	}
}

ClassFactory container = new ClassFactory();

container.RegisterType<FuncConsumer>();
container.RegisterType<TestClass>();

//Successfully created with the ability to create TestClass
FuncConsumer f = container.ManufactureType<FuncConsumer>();

Simplified Registrations

Registrations no longer require the separation of contract and implement so just an implementation can be registered.  Usage example:

ClassFactory container = new ClassFactory();

container.RegisterType<TestClass>();

var t = container.ManufactureType<TestClass>();

Largest Resolvable Constructor

This is quite a complicated area that is worthy of a blog post itself but OCInject’s behaviour has changed.  When creating a type the constructors are ordered so the largest, in terms of parameters, is first.  It then looks at each parameter and to see if it can resolve it, first by checking ‘resolve time args’ (values passed in when the resolve is requested, normally from generated factories) then by seeing if the type is a registered contract within the container.   It does not check if the type can be created just that it knows about it, if it’s registered it assumes it can be created.

The first completely resolvable constructor will be used to construct the type.

Unresolveable Callback

If the container is unable to resolve the type you can now register a function that is called before the container throws an exception.  To do this you need register a Func<Object, Type> with the CallToResolve propriety.  Returning null will cause the container to throw an exception.  Usage example:

ClassFactory container = new ClassFactory();

container.CallToResolve = (type) => { return new TestClass(); };

ITestClass manufacturedType = factory.ManufactureType<ITestClass>();

Child Container Support

Calling CreateChildContainer() will return a new ClassFactory object with no registrations but a link back to the parent.  If a type is not known to the child it will ask the parent to fulfil the request.  Any registrations with the child will not effect the parent and singletons registered with the child will be disposed when it is. Usage example:

ClassFactory container = new ClassFactory();
ClassFactory child = factory.CreateChildContainer();
VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)

Written by Will

March 22nd, 2010 at 10:00 am

Posted in Uncategorized

Tagged with , ,

Introducing OCInject

with 2 comments

**Update** I’ve created a CodePlex project: http://ocinject.codeplex.com

I’ve been learning about Dependency Injection (DI) and Inversion of Control, one of the ways I’ve done this is by creating my own mini DI framework for use in DirLinker.  I’ve, also, looked at the big name frameworks and read lots along the way but I want to give something back to the community that has taught me so much.  So I’m releasing my tiny DI framework used in DirLinker independently as OCInject.

OK, So Why Is This Different To X

My aim when creating OCInject was to create something that can be used in small projects, single exe utilities or one off apps, where you want the advantages of a DI container but without the overhead of Castle, Autofac, et al.  So consider this DI lite, you simply take the two files, IClassFactory.cs and ClassFactory.cs, and drop them in to your project.  That’s it, done, no external dependency and no XML config file. What do you get?

Features:

  • A DI Container with fluent like configuration
  • Ability to resolve constructor parameters for registered types and passed in constructor arguments
  • Runtime delegate factory generation
  • Pseudo session support via IDisposable.

The feature list is tiny and is very unlikely to grow; well maybe by one, singleton support.  It is not meant to compete with or to replace anything that already exists.

How To Use It

Basic Resolution

As I said above first thing to do is copy IClassFactory.cs and ClassFactory.cs into your project, then fill the container and resolve your type.  For example

    public interface IMyClass
    {    }

    public class MyClass : IMyClass
    {  }

    public class MyApp
    {
        public void Run()
        {
            IClassFactory factory = new ClassFactory();

            factory.RegisterType<IMyClass, MyClass>();

            IMyClass myClass = factory.ManufactureType<IMyClass>();
        }
    }

If the class has dependencies we can inject these just by specifying them as constructor arguments on our class and the container will resolve them if they are registered.  For example

public interface IMyClassWithDepend
{}

public class MyClassWithDepend
{
    public MyClassWithDepend(IMyClass depend)
    { }
}

public class MyApp
{
    public void Run()
    {
        IClassFactory factory = new ClassFactory();

        factory.RegisterType<IMyClassWithDepend, MyClassWithDepend>();
        factory.RegisterType<IMyClass, MyClass>();

        IMyClassWithDepend myClass = factory.ManufactureType<IMyClassWithDepend>();
    }
}

Auto Delegate Factories

For auto generated delegate factories we need to create a delegate that returns the contract type. Then register this with the container using the WithFactory<T> method when registering the type. For example:

public delegate IMyClassCreatedByFactory FactoryMethodName();

public interface IMyClassCreatedByFactory
{ }

public class MyClassCreatedByFactory
{ }

public class FactoryConsumer : IFactoryConsumer
{
    FactoryMethodName _Factory;
    public FactoryConsumer(FactoryMethodName factory)
    { _Factory = factory; }

    public void DoWork()
    {
        IMyClassCreatedByFactory c = _Factory();
    }
}

public class MyApp
{
    public void Run()
    {
        IClassFactory factory = new ClassFactory();

        factory.RegisterType<IFactoryConsumer, FactoryConsumer>();
        factory.RegisterType<IMyClassCreatedByFactory, MyClassCreatedByFactory>()
            .WithFactory<FactoryMethodName>();

        IFactoryConsumer myClass = factory.ManufactureType<IFactoryConsumer>();
		myClass.DoWork();
    }
}

Auto Delegate Factories With Parameters

Delegate factories can take parameters and pass them on to the constructors of objects.  This is still a bit limited because it doesn’t intelligently select the correct constructor, just the first it comes across (maybe a feature for the future :P ).  To use them just add parameters to your delegate declaration and a create a constructor on your implementation type that matches.  You can still have dependencies that are resolved by the container in the constructor, for example:

public delegate IMyClassCreatedByFactory FactoryMethodName(String param1);

public interface IMyClassCreatedByFactory
{ }

public class MyClassCreatedByFactory
{
    public MyClassCreatedByFactory(IMyClass myClass, String param)
    { }
}

public class FactoryConsumer : IFactoryConsumer
{
    FactoryMethodName _Factory;
    public FactoryConsumer(FactoryMethodName factory)
    { _Factory = factory; }

    public void DoWork()
    {
        IMyClassCreatedByFactory c = _Factory("OCInject filling a gap that doesn't exist");
    }
}

public class MyApp
{
    public void Run()
    {
        IClassFactory factory = new ClassFactory();

		factory.RegisterType<IMyClass, MyClass>();
        factory.RegisterType<IFactoryConsumer, FactoryConsumer>();
        factory.RegisterType<IMyClassCreatedByFactory, MyClassCreatedByFactory>()
            .WithFactory<FactoryMethodName>();

        IFactoryConsumer myClass = factory.ManufactureType<IFactoryConsumer>();
        myClass.DoWork();
    }
}

Where to Get it From and Further Examples

You can download it from BitBucket at http://bitbucket.org/humblecoder/ocinject/.  I don’t have any documentation at the moment but you can look at the DirLinker source and the unit tests for OCInject for more examples.

Enjoy and I hope someone finds it useful :)

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)

Written by Will

February 19th, 2010 at 1:13 pm

I Was Wrong About Delegate Factories “Micro Optimisations”

without comments

In my previous post I talked about creating typed delegate factories, towards the end of the post I talked about optimising the performance by avoiding boxing when passing value type parameters around.  My premise was that if we could use generics to select strongly typed method signatures for the method that constructs the type we could avoid the boxing and unboxing of value types.  I think outside of dependencies, the most common constructor arguments is going to be value types.  But I was wrong.

Why?

It all boils down to Constructor.Invoke, this is the method my tiny dependency injection framework uses to create new instances of objects from the container.  Its only signature takes params object[] so all our hard work is useless because the values will be boxed for this call.

The biggest thing I was wrong about, though, was that reflection is quicker than boxing.  Lets look at the timing of the reflective generic approach:

reflective

So generating the factory takes 79ms when you reflect over the type and remove any generics.  But what about calling using params object[].

bloxing

This takes 31ms to create the factory.  So it is quite clear that, at least upfront, using the param approach is substantially quicker.  One thing I will point out is, the tests didn’t use the factories to create any types.  But the values will still be boxed when passed to the invoke method so I would still expect the second method to be more performant.

My point is that we need to look more closely at how we are going to use the code and if there is any optimisation, like caching the generated delegates, that would speed up calls after taking an initial hit.  If we didn’t need to make the call Constructor.Invoke would the second approach still be quicker overall in our application?

VN:F [1.9.3_1094]
Rating: 4.0/5 (2 votes cast)

Written by Will

February 13th, 2010 at 1:06 am

Posted in .NET, C#, CodePlex

Tagged with , , , ,

Get Adobe Flash playerPlugin by wpburn.com wordpress themes