I introduced the factory facility of windsor (or actually castle microkernel) at the end of my previous project and I submitted some patches on it's programmatic use, and there is not so much documentation on it (well, not any on that part) so a little writeup was in order.
If you don't know what a container/IoC/DI is, and like to know concepts, check this out. If you don't know and want an example of windsor, check this out. A container is a little piece of frameworkish code that takes care of constructing your instances for you in a OO program, so you don't have to keep track of what goes where which simplifies alot.
You use it by first describing the classes you use and then asking for an instance of one. For example, you can tell it that you have a class D that uses an instance of class A and C. Class C in turn needs an instance of a class B. This is done in some init area of your code. Then in the program, you can say give me a D (resolve), and it will create A, create B and use it to create C and use these to create a D and return to you. Example classes:
public class A { }
public class B { }
public class C
{
public C(B instanceOfB) { }
}
public class D
public D(A instanceOfA, C instanceOfC) { }
Example use in test:
[Test]
public void MostBasicExample()
IKernel container = new DefaultKernel();
container.AddComponent("keyForClassA", typeof(A));
container.AddComponent("keyForClassB", typeof(B));
container.AddComponent("keyForClassC", typeof(C));
container.AddComponent("keyForClassD", typeof(D));
D anAInstance =
container.Resolve("keyForClassD", typeof(D)) as D;
Assert.That(anAInstance, Is.TypeOf(typeof(D)));
Concepts/acronymns are "inversion of control" and "dependency injection", I like to refer to it as just a container, it's imprecise and contextual instead of sacrificing simplicity to get precise, but that's who I am. It's just oo, really. There are several such pieces of container code for .NET; castle windsor, spring.net and the objectbuilder framework from ms that is used in their application blocks, etc. I personally favor the castle project implementation because of it's ease of use and simplicity.
I feel the default container lacks some stuff, so I wrap it and add generics, methods that omit the key (sometimes I know that I will only have one implementation of a class in a system) and that look at metadata for attributes in an assembly and auto register. I make my wrapper a singleton. I slap on a custom attribute I call "ContainerComponent" on the example classes above and the test becomes:
Container.Instance.AddFromAssemblyOf<A>();
D anAInstance = Container.Instance.Resolve<D>();
(In fairness, there have been some recent commits that move toward this.)
Windsor can be extended via facilities, small pieces of code that add small pieces of functionality. The factory facility allows us to tell windsor to use a certain method (instance or static) on a class to create an instance of a class. I added some simple methods to add factories programmatically. Here are some example classes:
public interface IUserRepository
void UpdateUser();
public class UserRepositoryImplementation : IUserRepository
public void UpdateUser()
public class UserRepositoryFactory
public UserRepositoryImplementation Create()
return new UserRepositoryImplementation();
Here is an example test using microkernel and programmatically using the factory support facility (currently in trunk):
public void FactoryResolveWithProposedFacilityPatch()
IKernel kernel = new DefaultKernel();
FactorySupportFacility facility =
new FactorySupportFacility();
kernel.AddFacility("factory.support", facility);
string userRepositoryKey = "userrepository";
facility.AddFactory<IUserRepository, UserRepositoryFactory>
(userRepositoryKey, "Create");
IUserRepository userRepository = kernel.Resolve(
userRepositoryKey,
typeof(IUserRepository)) as IUserRepository;
Assert.That(userRepository,
Is.TypeOf(typeof(UserRepositoryImplementation)));
I think that is messy, if we use a little container wrapper and say that we have don't need the key to differentiate
between implementations, it becomes:
public void FactoryResolveWithContainer_NoKey()
Container.Instance
.AddFactory<IUserRepository, UserRepositoryFactory>
("Create");
IUserRepository userRepository =
Container.Instance.Resolve<IUserRepository>();
Here are some example classes for a fuller example:
public class FileStorageService
public class AnnounceService
private FileStorageService _storage;
private IUserRepository _userRepo;
public IUserRepository UserRepo
get { return _userRepo; }
public AnnounceService( FileStorageService fileStorage,
IUserRepository userRepo )
_storage = fileStorage;
_userRepo = userRepo;
Example:
public void FactoryResolveWithContainer_FullerExample()
Container container = Container.Instance;
container.AddFactory<IUserRepository,
UserRepositoryFactory>("Create");
container.AddComponent<FileStorageService>();
container.AddComponent<AnnounceService>();
AnnounceService announceService =
container.Resolve<AnnounceService>();
Assert.That(announceService.UserRepo,
You can set parameters for the factory method at configuration time and at runtime. Will continue with that and post code later on, stay tuned.
Remember Me