如何为 ICollection<T> where T : IMyInterface 定义扩展方法而不在方法定义中指定 T
How to Define Extension Method for ICollection<T> where T : IMyInterface without Specifying T in the Method Definition
背景:我想在将 DTO 映射到实体时加入业务规则。我认为将映射封装到扩展方法中将是一个很好的途径。
IEntityDto是所有可以直接映射到实体的DTO实现的接口。
单个实例工作正常:
public static TEntity MapTo<TEntity>(this IEntityDto dto)
{
... Run Business Rules that don't require db access ...
return AutoMapper.Mapper.Map<TEntity>(dto);
}
我也想以同样的方式扩展 ICollection:
public static ICollection<TEntity> MapToCollection<TEntity>(this ICollection<IEntityDto> dtos)
{
... Run Business Rules that don't require db access ...
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
不幸的是,当应用于 IEntityDto 的 ICollection 时,MapToCollection 不会显示在上下文菜单中或编译。
我缺少什么才能让它工作?我是否只需要在 T 是 IEntityDto 的地方扩展 ICollection?我希望在调用扩展方法时不必包含 DTO 类型。
public static ICollection<TEntity>MapToCollection<TDto,TEntity>(this ICollection<TDto> dtos) where TDto: IEntityDto
{
... Do Work and Return ...
}
以上有效,但我希望从集合中推断出 T。
谢谢!
我假设发生这种情况是因为您要调用此扩展方法的变量实际上不是 ICollection<IEntityDto>
类型,而是 ICollection<MyEntityDto>
类型。
试试这个:
public static class ExtensionMethods
{
public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
this ICollection<TEntityDto> dtos) where TEntityDto : IEntityDto
{
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
}
此方法接受通用 ICollection<TEntityDto>
而不是 ICollection<IEntityDto>
,这使其适用于 ICollection<MyEntityDto>
.
等情况
以下是您将如何使用它:
Collection<MyEntityDto> collection = ...
var result = collection.MapToCollection<MyEntity, MyEntityDto>();
您有效地需要一个签名为
的方法
public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
this ICollection<TEntityDto> dtos)
where TEntityDto : IEntityDto
...但这会迫使您指定 both 类型参数,我知道您不想这样做。
你可以做的是分两步进行,例如
public static class DtoExtensions
{
public static CollectionMapper<TEntityDto> Map(this ICollection<TEntityDto> dtos)
where TEntityDto : IEntityDto
{
return new CollectionMapper<TEntityDto>(dtos);
}
}
public class CollectionMapper<TEntityDto> where TEntityDto : IEntityDto
{
private readonly ICollection<TEntityDto> dtos;
public CollectionMapper(ICollection<TEntityDto> dtos)
{
this.dtos = dtos;
}
public ICollection<TEntity> To<TEntity>()
{
// Business rules...
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
}
您现在可以使用:
var result = collection.Map().To<FooEntity>();
Map
调用推断 TEntityDto
,并且您在 To
调用中指定 TEntity
。
背景:我想在将 DTO 映射到实体时加入业务规则。我认为将映射封装到扩展方法中将是一个很好的途径。
IEntityDto是所有可以直接映射到实体的DTO实现的接口。
单个实例工作正常:
public static TEntity MapTo<TEntity>(this IEntityDto dto)
{
... Run Business Rules that don't require db access ...
return AutoMapper.Mapper.Map<TEntity>(dto);
}
我也想以同样的方式扩展 ICollection:
public static ICollection<TEntity> MapToCollection<TEntity>(this ICollection<IEntityDto> dtos)
{
... Run Business Rules that don't require db access ...
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
不幸的是,当应用于 IEntityDto 的 ICollection 时,MapToCollection 不会显示在上下文菜单中或编译。
我缺少什么才能让它工作?我是否只需要在 T 是 IEntityDto 的地方扩展 ICollection?我希望在调用扩展方法时不必包含 DTO 类型。
public static ICollection<TEntity>MapToCollection<TDto,TEntity>(this ICollection<TDto> dtos) where TDto: IEntityDto
{
... Do Work and Return ...
}
以上有效,但我希望从集合中推断出 T。
谢谢!
我假设发生这种情况是因为您要调用此扩展方法的变量实际上不是 ICollection<IEntityDto>
类型,而是 ICollection<MyEntityDto>
类型。
试试这个:
public static class ExtensionMethods
{
public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
this ICollection<TEntityDto> dtos) where TEntityDto : IEntityDto
{
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
}
此方法接受通用 ICollection<TEntityDto>
而不是 ICollection<IEntityDto>
,这使其适用于 ICollection<MyEntityDto>
.
以下是您将如何使用它:
Collection<MyEntityDto> collection = ...
var result = collection.MapToCollection<MyEntity, MyEntityDto>();
您有效地需要一个签名为
的方法public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
this ICollection<TEntityDto> dtos)
where TEntityDto : IEntityDto
...但这会迫使您指定 both 类型参数,我知道您不想这样做。
你可以做的是分两步进行,例如
public static class DtoExtensions
{
public static CollectionMapper<TEntityDto> Map(this ICollection<TEntityDto> dtos)
where TEntityDto : IEntityDto
{
return new CollectionMapper<TEntityDto>(dtos);
}
}
public class CollectionMapper<TEntityDto> where TEntityDto : IEntityDto
{
private readonly ICollection<TEntityDto> dtos;
public CollectionMapper(ICollection<TEntityDto> dtos)
{
this.dtos = dtos;
}
public ICollection<TEntity> To<TEntity>()
{
// Business rules...
return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
}
您现在可以使用:
var result = collection.Map().To<FooEntity>();
Map
调用推断 TEntityDto
,并且您在 To
调用中指定 TEntity
。