I need to create runtime implementations based on some messages / properties that I receive from the server, which also need to be converted by the newly created object. I'm new to Autofac, but as far as I can see, there are two approaches to solving this problem.
Approach 1: registration of specialized plants
... builder.RegisterType<MTextField>().Keyed<IComponent>(typeof(TextFieldProperties)); builder.RegisterType<ComponentFactory>().As<IComponentFactory>(); public class ComponentFactory : IComponentFactory { private readonly IIndex<Type, IComponent> _lookup; public ComponentFactory(IIndex<Type, IComponent> lookup) { _lookup = lookup; } public IComponent Create(ComponentProperties properties) { var component = _lookup[properties.GetType()]; component.Transform(properties); return component; } }
Approach 2: Feature Registration
... builder.RegisterType<MTextField>().Keyed<IComponent>(typeof(TextFieldProperties)); builder.Register<Func<ComponentProperties, IComponent>>(c => { var context = c.Resolve<IComponentContext>(); return properties => { var component = context.ResolveKeyed<IComponent>(properties.GetType()); component.Transform(properties); return component; }; });
Questions:
I think this may be subjective, but I still wanted to ask.
- Which approach is preferable and why?
- Is there even a better solution?
- Is it really necessary to keep the context in "Approach 2"?
EDIT
ok, I played a bit with autofac. here is my current approach:
public class TransformerFactory<D, T> : ITransformFactory<D, T> where T : ITransform<D> { private readonly IIndex<Type, T> _lookup; public TransformerFactory(IIndex<Type, T> lookup) { _lookup = lookup; } public T Create(D data, Action<T> prepareInstance = null) { var instance = _lookup[data.GetType()]; if (prepareInstance != null) { prepareInstance(instance); } instance.Transform(data); return instance; } } builder.RegisterGeneric(typeof(TransformerFactory<,>)).As(typeof(ITransformFactory<,>)); // eg var x = container.Resolve<ITransformFactory<ComponentProperties, IComponent>>();
source share