Saturday, December 4, 2010

Registering definitions programmatically with Spring.net - Part 2 - Generic Definitions

As a continuation of my previous post, here is a short explanation of the same functionality described before but making use of type checking, so these are useful when you know the type you are implementing as opposed as the previous post.



So, here is the Definition class that takes care of the Generic types, is worth mentioning that the implementation of this interface is just a wrapper of the Type based Definition.

public interface IDefinition<T>
{
    IDefinition<T> Singleton();
    IDefinition<T> Prototype();

    IDefinition<T> StaticFactory<F>(Expression<Func<T>> call);
    IDefinition<T> Factory<F>(Expression<Func<F, T>> call);

    IDefinition<T> ConstructorArgument(object value);
    IDefinition<T> ConstructorArgument<D>();

    IDefinition<T> Property<V>(Expression<Func<T, V>> expression, V value);
    IDefinition<T> Property<D>(Expression<Func<T, D>> expression);
    IDefinition<T> Property(string propertyName, object value);
    IDefinition<T> Property<D>(string propertyName);
    IDefinition<T> AddAlias<A>();
}

And here are some tests that show how the API is consumed in this case:

Registering a type as Prototype.
[TestMethod]
public void RegisterSimplePrototypeGeneric()
{
     Context.Register<EmptyService>(d => d.Prototype());
     Verify.IsPrototype<EmptyService>();
}

or registering through a factory method;

[TestMethod]
public void RegisterWithFactoryGeneric()
{
     Context.Register<ServiceFactory>();
     Context.Register<ServiceWithConstructor>(d => d.Factory<ServiceFactory>(x => x.CreateService()));
   
      Verify.CanResolve<ServiceWithConstructor>();
}

or with dependencies through Setter properties;

[TestMethod]
public void RegisterWithSetterDependencyGeneric()
{
    Context.Register<Dependency>();
    Context.Register<ServiceWithSetterDependencies>(d => d.Property(c => c.Value, "value").Property(c => c.Dependency));

    var dependency = Verify.CanResolve<Dependency>();
    var service = Verify.CanResolve<ServiceWithSetterDependencies>();
   
    Assert.AreEqual("value", service.Value);
    Assert.AreSame(dependency, service.Dependency);
}

All these combinations can be combined as long as they represent something consistent with what you can do through spring configuration.

In next post I'll introduce the Sterotypes, and how they combine with the definitions to facilitate the declaration of several types that are similar.

If you feel curious the code is at the google code repository

'till the next post!

No comments:

Post a Comment