Hi there!
Hmm, this is probably me just being dim about Generics, but I am trying to return a 'generic' list from a series of Browse handlers using the Command Pattern. The call is made from a generic place and does the following:
DomainEntityBrowseHandlerFactory
.Create(domainEntityType).Execute(searchCriteria)The code for the factory is as follows
public static class DomainEntityBrowseHandlerFactory{
public static IDomainEntityBrowseHandler Create(string domainEntityType)
{
if (domainEntityType == typeof(CreditReviewStatus).Name)
return new CreditReviewStatusBrowseHandler();
else if (domainEntityType == typeof(CreditReviewType).Name)
return new CreditReviewTypeBrowseHandler();
else if (domainEntityType == typeof(CreditRiskStatus).Name)
return new CreditRiskStatusBrowseHandler();
else if (domainEntityType == typeof(CreditRiskStatusReason).Name)
return new CreditRiskStatusReasonBrowseHandler();
else
throw new PresentationLayerException(String.Format("Unable to locate {0} Browse request handler"));
}
}
It attempts to return a Handler which implements the IDomainEntityBrowseHandler interface, which is defined as follows:
public interface IDomainEntityBrowseHandler
where TEntity : NamedDomainEntity
{
///
/// Provides a contract for all the simple entity browsers
///
///
///
IList
}
an example of one of the implmentations of the handler is as follows
public class CreditReviewTypeBrowseHandler : IDomainEntityBrowseHandler<CreditReviewType>
{
#region
IDomainEntityBrowseHandler Memberspublic IList<CreditReviewType> Execute(NamedDomainEntitySearchCriteria searchCriteria)
{
return DomainEntityService<CreditReviewType>.FindBySearchCriteria(
RepositoryFactory.Instance.GetBaseRepository<CreditReviewType>(
NamedDomainEntityConfigurationFactory.GetUsageArguments<CreditReviewType>()
),
searchCriteria
);
}
#endregion
}
All the handler return an IList of their specific type, and they all inherit from NamedDomainEntity, so I figure that will work, as I resolve the TEntity in each handler, unfortunately it is the factory which fails me, in that where I've specified the return type for the Create method it is expecting IDomainEntityBrowseHandler to have
I've tried this and it compiles, but surely this means that I have to specify what type it is when I call create, and I don't know that, so the object is defeated, if you'll pardon the pun!
public static IDomainEntityBrowseHandlerwhere TEntity : NamedDomainEntity
{
if (domainEntityType == typeof(CreditReviewStatus).Name)
return new CreditReviewStatusBrowseHandler() as IDomainEntityBrowseHandler
else if (domainEntityType == typeof(CreditReviewType).Name)
return new CreditReviewTypeBrowseHandler() as IDomainEntityBrowseHandler
else if (domainEntityType == typeof(CreditRiskStatus).Name)
return new CreditRiskStatusBrowseHandler() as IDomainEntityBrowseHandler
else if (domainEntityType == typeof(CreditRiskStatusReason).Name)
return new CreditRiskStatusReasonBrowseHandler() as IDomainEntityBrowseHandler
else
throw new PresentationLayerException(String.Format("Unable to locate {0} Browse request handler", domainEntityType));
}
So I'm stumped, I would be stoked if someone could point me in the right direction
Many thanks in advance
Colin
Tim McCarthyPosted Mar 3, 2008, 2:45 AM
Colin,
You need to make your factory return a type of IDomainEntityBrowseHandler. I would change the signature of the factory method to the following:
public static IDomainEntityBrowseHandler Create()
Get rid of the domainEntityType string argument, you do not need it. In your configuration, I would create a mapping between the short type name of the TEntity, i.e. CreditReviewType, and then the value for the mapping would be the fully qualified assembly name that contains that type. You can get the short type name of the TEntity Generic parameter by using the following code: typeof(TEntity).Name.
Then, in your factory you could use Activator.CreateInstance(Type type) to create the correct type from the configuration mapping. Since Activator.CreateInstance returns System.Object, you can cast it to IDomainEntityBrowseHandler and return the value. The compiler will be happy about this, and so will your code :)
I hope this helps!