Prefiero tener el tipo que desea crear una instancia para un valor específico en un archivo de configuración. algo como:
<TypeMappings>
< nombre TypeMapping = tipo "vida" = "Entities.LifeEntity, Entidades"/>
< TypeMapping name = tipo "propiedad" = "Entities.PropertyEntity, Entidades"/>
< nombre TypeMapping = tipo "discapacidad" = "Entities.DisabilityEntity, Entidades"/>
< TypeMapping name = tipo "tarjeta de crédito" = "Entities.CreditCardEntity, Entidades"/>
</TypeMappings >
Dentro de su método que a continuación podría extraer todos los registros del archivo de configuración, encontrar el juego uno y el uso de reflexión para crear una instancia del tipo, si no se encuentra el registro, se lanza una excepción.
Aquí hay un código de ejemplo:
namespace Entities
{
public interface IResultEntity
{
}
public class LifeEntity : IResultEntity
{
public override string ToString()
{
return("I'm a Life entity");
}
}
public class PropertyEntity : IResultEntity
{
public override string ToString()
{
return("I'm a Property Entity");
}
}
public class CreditCardEntity : IResultEntity
{
public override string ToString()
{
return("I'm a CreditCard Entity ");
}
}
public class DisabilityEntity : IResultEntity
{
public override string ToString()
{
return("I'm a Disability Entity");
}
}
}
public static Entities.IResultEntity GetEntity(string entityTypeName,string fileName)
{
XDocument doc = XDocument.Load(fileName);
XElement element = doc.Element("TypeMappings").Elements("TypeMapping")
.SingleOrDefault(x => x.Attribute("name").Value == entityTypeName);
if(element == null)
{
throw new InvalidOperationException("No type mapping found for " + entityTypeName);
}
string typeName = element.Attribute("type").Value;
Type type = Type.GetType(typeName);
Entities.IResultEntity resultEntity = Activator.CreateInstance(type) as Entities.IResultEntity;
if(resultEntity == null)
{
throw new InvalidOperationException("type mapping for " + entityTypeName + " is invalid");
}
return resultEntity;
}
public static void Main()
{
try
{
Entities.IResultEntity result = GetEntity("life", @"c:\temp\entities.xml");
Console.WriteLine(result);
result = GetEntity("property", @"c:\temp\entities.xml");
Console.WriteLine(result);
result = GetEntity("disability", @"c:\temp\entities.xml");
Console.WriteLine(result);
result = GetEntity("creditcard", @"c:\temp\entities.xml");
Console.WriteLine(result);
result = GetEntity("foo", @"c:\temp\entities.xml");
Console.WriteLine(result);
}
}
Una gran cantidad de marcos de DI le permiten proporcionar múltiples registros para una interfaz que se puede consulta basada en metadatos. Consulte this link sobre cómo MEF exporta usando metadatos.
Así es como normalmente me acerco a una fábrica, especialmente en bibliotecas donde las aplicaciones cliente pueden querer agregar sus propias implementaciones. – Joon
Esa fuente para obtener más enlace de información ya no está disponible, ¿hay alguna posibilidad de que se aloje en otro lugar? ¿O hay una publicación equivalente en alguna parte? –
@Sam Heuck He vinculado una versión archivada – Lennart