Access to the type the instance is being resolved for in a factory?

Jun 17, 2009 at 10:42 AM

This may have been answered elsewere but if it has I can't seem to find it. :(

I need to be able to register a factory that has the following characteristics

  1. Singleton factory instance
  2. Has access to the type the instance is is being resolved for

Here are two example scenarios that I want to be able to support:

Scenario 1:

Given an interface of

 

public interface ISerializer<T>
{
    void Save(T obj);
}

 

and a backing implementation that uses DataContractSerializer where the concept of KnownTypes is present I want to be able to register a factory that would do this....

 

container.RegisterFactory>(typeBeingSerialized => 
    {
         // discover and cache will use a memoization technique to cache on "typeBeingSerialized" so the discovery only happens per type
         IEnumerable knownTypes = DiscoverAndCacheAllTypesInType(typeBeingSerialized);
         return new DataContractSerializer(typeBeingSerialized, knownTypes);
    });

This gives me several advantages not the least of which is I don't have to manually walk the tree to discover all the "KnownTypes" for the object being serialized but instead do it dynamicly while still only doing the discovery a single time.

Scenario 2:

Given a simple ILog interface where I want to configure a different set of listeners/etc based on the type that the instance is being created for.  Sample code

public interface ILog { void Warn(string msg); }

public class LogFactory
{
    public static ILog CreateForType(Type type) {/*create ILog based on some business logic rules */ }
}

public class LogConsumerA
{
    public LogConsumerA(ILog log) {}
}
public class LogConsumerB
{
    public LogConsumerB(ILog log) {}
}

container.RegisterFactory<ILog>(typeBeingCreated => LogFactory.CreateForType(typeBeingCreated));

This lets me create ILog instances with different configurations for consumers - LogConsumerA might get a console based ILog instance with filters for Errors only but LogConsumerB gets one for Debug.

I am aware of the StaticFactoryExtension and I suspect I need to create an extension to permit this kind of behavior but I am not seeing where I can get type that the resolution is being done for.

Does anybody have any pointers on how to accomplish this?
Thanks

 

Oct 28, 2009 at 6:47 PM

You will need to write an extension for this. The type being requested is available inside the BuilderContext passed into the *Buildup methods - it's in the BuildKey property. Take a look at any of the strategies in the Unity source, they just about all use this.

Nov 19, 2009 at 10:19 AM

Hi mwatts42

I'm also interested in a solution for scenario 2. Have you already found a solution for this?

I saw an easy solution for the Ninject container where they have the "provider" concept and where you can access the type on which the ILog object should get injected (http://stackoverflow.com/questions/719346/using-ninject-or-some-other-container-how-can-i-find-out-the-type-that-is-reque)

But with the unity container, I'm struggling with creating a custom extension that could do the same.