Skip to content

jamiebriant/BinaryFinery.IOC

Repository files navigation

BinaryFinery.IOC

The Rewrite

I've rewritten BF.IOC from scratch. v1.0 grouped many singleton specifications into interfaces. In this version, singletons are specified explicitly at runtime.

What's in the current version:

  1. Singleton generation.
  2. Object injection using constructors only. Which is actually a very bad habit so don't do it.
  3. Detects cyclic dependencies (throws exception)
  4. Injection using properties. Add an [Inject] attribute.
  5. --Injection using methods. Add an [Inject] attribute.-- (Yeah, I haven't redone this yet).
  6. Manual injection. You can manually inject classes if you have the context handy, using the new Inject(object) method of IContext.
  7. You can inject the context itself.
  8. Post-construction methods.

How To Use It

The application can then realise this context as follows:

CM = ContextSystem.RootContext;
CM.RegisterSingleton<IOSImageCache,IImageCache>();
CM.RegisterSingleton<SomeConcreteClass>();

var context = CM.Create<IImageCache>();

Cyclic Dependencies in Constructors

There are a couple of ways around cyclic dependencies in constructors, though all of them will throw an exception in the case that a dependency is actually used in the constructor itself.

  1. Use object allocation followed by object initialization.
  2. Use wrappers if the dependency is an interface.

Method 1 is not available in silverlight, nor I suspect MonoTouch. Method 2 is only available if one of the cyclic dependencies is an interface, and only then if code can be generated. These methods allow the cycle to be broken such that the first one created is given references to either an unitialized object, or an uninitialized proxy. If the constructor attempts to use that dependency then it will be handed an exception, or worse, it will fail at some later time.

As a result, BF.IOC will never handle cyclic dependencies in constructors other than to throw an exception.

Injection Complete Methods

[InjectionCompleteHandler]
public void InjectionComplete()
{
	// do something interesting.
}

This method will be called after all objects have been resolved and injected.

Note, that at this stage, all the required objects have been injected, but they may not be fully injected: they may also have an InjectionCompleteHandler that needs to be called before they are ready. In this case, use regular events to request notification.

If an InjectionCompleteHandler method makes calls that call the context, and that results in more objects being created, any InjectionCompleteHandler calls for the new objects are scheduled to be called after the original groups ICH handler methods are called.

Note that because of the systems ability to handle cyclic dependencies, the order of these calls is not guaranteed.

Note there are no tests that assert this behavior. The order should really not be relied upon.

Background

This is my fifth IOC/DI framework. The first three were written several years ago, and the third iteration is still in use today in a robust C# graphical application. The fourth built on the ideas of the third but proved to be needlessly complex. This latest version is a complete rewrite based on what I needed for two different needs: mobile apps and servers.

About

An IoC / DI container in C#

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages