有没有办法让C#泛型处理这种情况
当出现以下情况时,我对充斥着行的代码感到不满意有没有办法让C#泛型处理这种情况,c#,generics,C#,Generics,当出现以下情况时,我对充斥着行的代码感到不满意 var queryResult = _queryDispatcher.Dispatch<CustomerByIdQuery, CustomerByIdQueryResult>(customerByIdQuery).Customer; 有没有办法用泛型来实现这一点 这是密码 interface IQuery{} interface IQueryResult{} interface IQueryHandler&l
var queryResult = _queryDispatcher.Dispatch<CustomerByIdQuery, CustomerByIdQueryResult>(customerByIdQuery).Customer;
有没有办法用泛型来实现这一点
这是密码
interface IQuery{}
interface IQueryResult{}
interface IQueryHandler<TQuery, TQueryResult> : where TQueryResult:IQueryResult where TQuery:IQuery
{
TQueryResult Execute(TQuery query);
}
interface IQueryDispatcher
{
TQueryResult Dispatch<TQuery, TQueryResult>(TQuery query) where TQuery:IQuery where TQueryResult:IQueryResult
}
class GenericQueryDispatcher : IQueryDispatcher
{
public TQueryResult Dispatch<TQuery, TQueryResult>(TQuery parms)
{
var queryHandler = queryRegistry.FindQueryHandlerFor(TQuery);
queryHandler.Execute
}
}
class CustomerByIdQuery : IQuery
{
public int Id { get; set; }
}
class CustomerByIdQueryResult : IQueryResult
{
public Customer {get; set;}
}
class CustomerByIdQueryHandler : IQueryHandler
{
public CustomerByIdQueryResult Execute(TQuery query)
{
var customer = _customerRepo.GetById(query.Id);
return new CustomerByIdQueryResult(){Customer = customer};
}
}
public class SomeClassThatControlsWorkFlow
{
IQueryDispatcher _queryDispatcher;
public SomeClassThatControlsWorkFlow(IQueryDispatcher queryDispatcher)
{
_queryDispatcher = queryDispatcher;
}
public void Run()
{
var customerByIdQuery = new CustomerByIdQuery(){Id=1};
//want to change this line
var customer = _queryDispatcher.Dispatch<CustomerByIdQuery, CustomerByIdQueryResult>(customerByIdQuery).Customer;
}
}
是的,这是可能的,但是您必须使
Dispatch
方法的参数通用(这样,编译器可以从方法参数推断类型参数)。为此,您首先需要一个通用版本的IQuery
和IQueryResult
接口:
interface IQuery<TQuery, TQueryResult> : IQuery {}
interface IQueryResult<T> : IQueryResult
{
T Result { get; }
}
class CustomerByIdQuery : IQuery, IQuery<int, Customer>
{
public int Id { get; set; }
}
class CustomerByIdQueryResult : IQueryResult, IQueryResult<Customer>
{
public Customer Result {get; set;}
}
现在,您可以为接受通用参数的Dispatch
添加重载:
interface IQueryDispatcher
{
IQueryResult<TQueryResult> Dispatch<TQuery, TQueryResult>(IQuery<TQuery, TQueryResult> parms);
}
class GenericQueryDispatcher : IQueryDispatcher
{
public TQueryResult Dispatch<TQuery, TQueryResult>(IQuery<TQuery, TQueryResult> parms)
{
// TODO implement
}
}
我无法摆脱演员阵容,但这正是我想要的
public interface IQueryDispatcher
{
TQueryResult Dispatch<TParameter, TQueryResult>(IQuery<TQueryResult> query)
where TParameter : IQuery<TQueryResult>
where TQueryResult : IQueryResult;
}
public interface IQueryHandler<in TQuery, out TQueryResult>
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult
{
TQueryResult Retrieve(TQuery query);
}
public interface IQueryResult { }
public interface IQuery { }
public interface IQuery<TQueryResult> : IQuery { }
public class QueryDispatcher : IQueryDispatcher
{
readonly IQueryHandlerRegistry _queryRegistry;
public QueryDispatcher(IQueryHandlerRegistry queryRegistry)
{
_queryRegistry = queryRegistry;
}
public TQueryResult Dispatch<TQuery, TQueryResult>(IQuery<TQueryResult> query)
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult
{
var handler = _queryRegistry.FindQueryHandlerFor<TQuery, TQueryResult>(query);
//CANT GET RID OF CAST
return handler.Retrieve((TQuery)query);
}
}
public interface IQueryHandlerRegistry
{
IQueryHandler<TQuery, TQueryResult> FindQueryHandlerFor<TQuery, TQueryResult>(IQuery<TQueryResult> query)
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult;
}
public class GetCustByIdAndLocQuery : IQuery<CustByIdAndLocQueryResult>
{
public string CustName { get; set; }
public int LocationId { get; set; }
public GetCustByIdAndLocQuery(string name, int locationId)
{
CustName = name;
LocationId = locationId;
}
}
public class CustByIdAndLocQueryResult : IQueryResult
{
public Customer Customer { get; set; }
}
public class GetCustByIdAndLocQueryHandler : IQueryHandler<GetCustByIdAndLocQuery, CustByIdAndLocQueryResult>
{
readonly ICustomerGateway _customerGateway;
public GetCustByIdAndLocQueryHandler(ICustomerGateway customerGateway)
{
_customerGateway = customerGateway;
}
public CustByIdAndLocQueryResult Retrieve(GetCustByIdAndLocQuery query)
{
var customer = _customerGateway.GetAll()
.SingleOrDefault(x => x.LocationId == query.LocationId && x.CustomerName == query.CustName);
return new CustByIdAndLocQueryResult() { Customer = customer };
}
}
public interface ICustomerGateway
{
IEnumerable<Customer> GetAll();
}
public class Customer
{
public string CustomerName { get; set; }
public int LocationId { get; set; }
public bool HasInsurance { get; set; }
}
公共接口调度程序
{
TQueryResult调度(IQuery查询)
其中t参数:iquiry
其中TQueryResult:IQueryResult;
}
公共接口IQueryHandler
问:伊奎里在哪里
其中TQueryResult:IQueryResult
{
TQueryResult检索(TQuery查询);
}
公共接口IQueryResult{}
公共接口IQuery{}
公共接口IQuery:IQuery{}
公共类QueryDispatcher:IQueryDispatcher
{
只读IQueryHandlerRegistry\u queryRegistry;
公共查询Dispatcher(IQueryHandlerRegistry查询注册表)
{
_queryRegistry=queryRegistry;
}
公共TQueryResult调度(IQuery查询)
问:伊奎里在哪里
其中TQueryResult:IQueryResult
{
var handler=\u queryRegistry.FindQueryHandlerFor(查询);
//摆脱不了石膏
return handler.Retrieve((TQuery)查询);
}
}
公共接口IQueryHandlerRegistry
{
IQueryHandler FindQueryHandlerFor(iQueryQuery)
问:伊奎里在哪里
其中TQueryResult:IQueryResult;
}
公共类GetCustByIdAndLocQuery:IQuery
{
公共字符串CustName{get;set;}
public int LocationId{get;set;}
公共GetCustByIdAndLocQuery(字符串名称,int locationId)
{
CustName=名称;
LocationId=LocationId;
}
}
公共类CustByIdAndLocQueryResult:IQueryResult
{
公共客户客户{get;set;}
}
公共类GetCustByIdAndLocQueryHandler:IQueryHandler
{
只读ICCustomerGateway\u customerGateway;
公共GetCustByIdAndLocQueryHandler(ICCustomerGateway customerGateway)
{
_customerGateway=customerGateway;
}
公共CustByIdAndLocQueryResult检索(GetCustByIdAndLocQuery查询)
{
var customer=\u customerGateway.GetAll()
.SingleOrDefault(x=>x.LocationId==query.LocationId&&x.CustomerName==query.CustName);
返回新的CustByIdAndLocQueryResult(){Customer=Customer};
}
}
公共接口ICustomerGateway
{
IEnumerable GetAll();
}
公共类客户
{
公共字符串CustomerName{get;set;}
public int LocationId{get;set;}
公共布尔值{get;set;}
}
此解决方案的唯一问题是类CustomerBydQuery:IQuery,IQuery{public int Id{get;set;}},因为只要我引入一个需要多个参数的查询,公共类CustomerByAndLocationQuery:IQuery,IQuery@jdev4ls这可能看起来很尴尬(使用F#会减少这种尴尬吗?),但这对于处理泛型来说并不是一个坏方法。一些核心的.Net定义使用它,例如Func
:我没有很好地解释我的意思,我会回答我的问题,这样你就可以知道我在说什么。
interface IQueryDispatcher
{
IQueryResult<TQueryResult> Dispatch<TQuery, TQueryResult>(IQuery<TQuery, TQueryResult> parms);
}
class GenericQueryDispatcher : IQueryDispatcher
{
public TQueryResult Dispatch<TQuery, TQueryResult>(IQuery<TQuery, TQueryResult> parms)
{
// TODO implement
}
}
var customerByIdQuery = new CustomerByIdQuery{Id=1};
var customer = _queryDispatcher.Dispatch(customerByIdQuery).Result;
public interface IQueryDispatcher
{
TQueryResult Dispatch<TParameter, TQueryResult>(IQuery<TQueryResult> query)
where TParameter : IQuery<TQueryResult>
where TQueryResult : IQueryResult;
}
public interface IQueryHandler<in TQuery, out TQueryResult>
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult
{
TQueryResult Retrieve(TQuery query);
}
public interface IQueryResult { }
public interface IQuery { }
public interface IQuery<TQueryResult> : IQuery { }
public class QueryDispatcher : IQueryDispatcher
{
readonly IQueryHandlerRegistry _queryRegistry;
public QueryDispatcher(IQueryHandlerRegistry queryRegistry)
{
_queryRegistry = queryRegistry;
}
public TQueryResult Dispatch<TQuery, TQueryResult>(IQuery<TQueryResult> query)
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult
{
var handler = _queryRegistry.FindQueryHandlerFor<TQuery, TQueryResult>(query);
//CANT GET RID OF CAST
return handler.Retrieve((TQuery)query);
}
}
public interface IQueryHandlerRegistry
{
IQueryHandler<TQuery, TQueryResult> FindQueryHandlerFor<TQuery, TQueryResult>(IQuery<TQueryResult> query)
where TQuery : IQuery<TQueryResult>
where TQueryResult : IQueryResult;
}
public class GetCustByIdAndLocQuery : IQuery<CustByIdAndLocQueryResult>
{
public string CustName { get; set; }
public int LocationId { get; set; }
public GetCustByIdAndLocQuery(string name, int locationId)
{
CustName = name;
LocationId = locationId;
}
}
public class CustByIdAndLocQueryResult : IQueryResult
{
public Customer Customer { get; set; }
}
public class GetCustByIdAndLocQueryHandler : IQueryHandler<GetCustByIdAndLocQuery, CustByIdAndLocQueryResult>
{
readonly ICustomerGateway _customerGateway;
public GetCustByIdAndLocQueryHandler(ICustomerGateway customerGateway)
{
_customerGateway = customerGateway;
}
public CustByIdAndLocQueryResult Retrieve(GetCustByIdAndLocQuery query)
{
var customer = _customerGateway.GetAll()
.SingleOrDefault(x => x.LocationId == query.LocationId && x.CustomerName == query.CustName);
return new CustByIdAndLocQueryResult() { Customer = customer };
}
}
public interface ICustomerGateway
{
IEnumerable<Customer> GetAll();
}
public class Customer
{
public string CustomerName { get; set; }
public int LocationId { get; set; }
public bool HasInsurance { get; set; }
}