Inject dependencies into StaticFactoryExtension

Jan 14, 2010 at 4:01 PM

Hi there

I have a question about the StaticFactoryExtension.
I have this factory found here for creating ESRI arcobjects both on server side and client side.
The thing is that the server side concrete factory has a dependency on IServerContext and the client side has not. So i´m wanted to know if the container can inject dependencies on the StaticFactory extension.

I want to be hable to inject the correct factory on business layers.
I admit im a little bit confused about this because in all examples i have read there is not dependencies like these.
The code for the factory:

namespace ArcObjectsFactory
{
    public interface IArcObjectFactory
    {
        object CreateObject(Type type);

        T CreateObject<T>();
    }
}
namespace ArcObjectsFactory
{
    public abstract class AbstractArcObjectFactory: IArcObjectFactory
    {
        public abstract object CreateObject(Type type);
       
        public T CreateObject<T>()
        {
            return (T)CreateObject(typeof (T));
        }  
    }
}
namespace ArcObjectsFactory
{
    public class AgsArcObjectFactory : AbstractArcObjectFactory
    {
        private IServerContext _serverContext;

        public IServerContext ServerContext
        {
            get { return _serverContext; }
            set { _serverContext = value; }
        }

        public AgsArcObjectFactory(IServerContext serverContext)
        {
            _serverContext = serverContext;
        }

        public override object CreateObject(Type type)
        {
            return ServerContext.CreateObject(GetTypeName(type));
        }

        protected virtual string GetTypeName(Type type)
        {
            return Path.GetFileNameWithoutExtension(type.Module.ScopeName) + "." + type.Name;
        }

    }
}
namespace ArcObjectsFactory
{
    public class ClientArcObjectFactory : AbstractArcObjectFactory
    {
        public override object CreateObject(Type type)
        {
            Type proxyClassType = type.Assembly.GetType(type.FullName + "Class");
            if (proxyClassType == null)
                throw new ArgumentException(string.Format("The type {0} is not an ArcObject type", type.FullName),
                                            "type");

            return Activator.CreateInstance(proxyClassType);
        }
    }
}

Can you point into any directions?
Thanks

Jan 15, 2010 at 2:52 AM

Ok, let me restate the problem to see if I understand it. You have a factory class you want to call from the container. That factory class may or may not have another dependency, which varies based on environment. Is that the basic gist of things?

In that case, it's pretty easy. First off, register IArcObjectsFactory, and map it to the appropriate concrete class for server or client environment. Make sure the container can resolve this.

Next, the static factory delegate receives the container itself as an argument, so you can use that to get the right one out. Something like this (I'll use Unity 2.0 syntax here because, well, it's better. ;-) Pretty straightforward to convert back to 1.2 though):

  container.RegisterType<MyArcObjectType>(new InjectionFactory(c => c.Resolve<IArcObjectsFactory>().CreateObject<MyArcObjectType>());

 

Jan 19, 2010 at 2:27 PM

Well...i didn´t want to create arcobjects from the container but i wanted to get the correct factory out of it instead and then inject the factory in the businesslayer.
I guess i dont need the static factory extension for that(i said i was confused about it :) )
I ended up building extension methods that register the correct factory class depending if you supply IServerContext instance or not.

public static IUnityContainer AddArcObjectsFactory<TFrom, TTo>(this IUnityContainer container, IServerContext serverContextInstance) where TTo : IArcObjectFactory
{
 //Register factory class
 container
  .RegisterFactoryClass<TFrom, TTo>();

 container.RegisterInstance<IServerContext>(serverContextInstance);
 container.Configure<InjectedMembers>()
  .ConfigureInjectionFor<TTo>(new InjectionConstructor(serverContextInstance));
 return container;
}
public static IUnityContainer AddArcObjectsFactory<TFrom, TTo>(this IUnityContainer container) where TTo : IArcObjectFactory
{
 container
  .RegisterFactoryClass<TFrom, TTo>();
 return container;
}

In any case thanks (i will keep this post for future reference :) )