lundi 24 octobre 2016

Implementation of factory pattern with derived classes has different properties

I have to decide service type and create instance with a string parameter on my service method. I have a controller action like below. I want to use my factory method and service like that but I cannot implement.

    public ActionResult Redirect(string entityType, Guid entityId)
    {
        var service = EntityInformationServiceFactory.GetService(entityType);
        var entity = service.GetEntityInformation<CaseInformation>(entityId);
       ...
    }

I have classes that derived from IEntityInformation interface. But every derived class has different properties. I don't want to use casting for my return value of. GetEntityInformation method.

This is my abstract service base class.

public abstract class EntityInformationService
{
    internal EntityInformationService()
    {
        CrmService = MSCRM.GetOrgService(true);
    }

    protected IOrganizationService CrmService { get; }
    protected abstract string EntityName { get; }
    protected abstract EntityType EntityType { get; }

    public abstract T GetEntityInformation<T>(Guid entityId) where T : IEntityInformation;
}

public class CaseInformation : IEntityInformation
{
    public CaseInformation(Guid entityId, string logicalName)
    {
        EntityId = entityId;
        LogicalName = logicalName;
    }

    public Guid EntityId { get; }
    public string LogicalName { get; }
}

public interface IEntityInformation { Guid EntityId { get; } }

And this is my service implementation.

internal class CaseInformationService : EntityInformationService
{
    public CaseInformationService()
    {
        EntityName = "incident";
        EntityType = EntityType.Case;
    }

    protected override string EntityName { get; }
    protected override EntityType EntityType { get; }

    public override T GetEntityInformation<T>(Guid entityId)
    {
        var result = CrmService.Retrieve(EntityName, entityId, new ColumnSet(true));
        var entityInformation = new CaseInformation(result.Id, result.LogicalName);
        return entityInformation;
    }
}

Because of return type of GetEntityInformation is T I cannot return an instance of CaseEntityInformation. How can I do this implementation without using casting, only generic type parameter ?

Aucun commentaire:

Enregistrer un commentaire