如何定义 ICollection其中 T : IMyInterface 而不在方法定义中指定 T

本文关键字:定义 IMyInterface 方法 何定义 ICollection 其中 | 更新日期: 2023-09-27 18:31:24

背景:我想在 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);
}

不幸的是,MapToCollection在应用于IEntityDto的ICollection时不会显示在上下文菜单上或编译中。

我错过了什么才能让它工作?我是否需要在 T 是 IEntityDto 的地方扩展 ICollection?我不希望在调用扩展方法时包含 DTO 类型。

public static ICollection<TEntity>MapToCollection<TDto,TEntity>(this ICollection<TDto> dtos) where TDto: IEntityDto
{
    ... Do Work and Return ...
}

以上有效,但我希望从集合中推断出T。

谢谢!

如何定义 ICollection<T>其中 T : IMyInterface 而不在方法定义中指定 T

实际上需要一个签名为

public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
    this ICollection<TEntityDto> dtos)
    where TEntityDto : IEntityDto

。但这会迫使您指定两个类型参数,我知道您不想这样做。

相反,您可以做的是分两跳,例如

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

我假设发生这种情况是因为您要调用此扩展方法的变量实际上不是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>();