我有一个允许用户关闭延迟加载的扩展方法。
public static IBaseEntityService<TEntity, TPrimaryKey> EnableLazyLoading<TEntity, TPrimaryKey>(
this IBaseEntityService<TEntity, TPrimaryKey> baseService,
bool enabled)
where TEntity :Entity<TPrimaryKey> where TPrimaryKey : struct
{
baseService.UnitOfWork.EnableLazyLoading(enabled);
baseService.UnitOfWork.EnableProxyCreation(enabled);
var type = baseService.GetType().;
return (type)baseService;
}
以下是基本界面的示例:
public interface IBaseEntityService<TEntity,TPrimaryKey> :
IBaseService<TEntity, TPrimaryKey>
where TEntity: Entity<TPrimaryKey> where TPrimaryKey : struct
{
TEntity FindByTenantId(Guid tenantId);
IBaseEntitySpecification<TEntity,TPrimaryKey> Specification { get; }
}
我们说我有这个实现IBaseEntityService<TEntity,TPrimaryKey>
接口的服务:
public IUserService: IBaseEntityService<User,int>
{
User FindByUserName(string username);
}
这是我想要实现的目标:
var user = _userService.EnableLazyLoading(false).FindByUserName("someUsername");
正如您在EnableLazyLoading(false)
之后的示例中所见,我可以使用FindByUserName
方法。目前,由于它只返回IBaseEntityService,我没有该选项。
我想确保扩展方法知道返回IUserService
,因为它实现了IBaseEntityService
。我知道它必须在某些时候强制转换它,我想避免为EnableLazyLoading
IUserService
方法的具体实现
我想到了类似的东西,但似乎我可以做一些事情,而不必隐式调用Cast方法:
public static TEntityService Cast<TEntity, TPrimaryKey, TEntityService>(
this IBaseEntityService<TEntity, TPrimaryKey> baseEntityService)
where TEntity : Entity<TPrimaryKey>
where TPrimaryKey : struct
where TEntityService : IBaseEntityService<TEntity, TPrimaryKey>
{
return (TEntityService) baseEntityService;
}
所以它可能会这样:
var user = _userService.EnableLazyLoading(false).Cast<IUserService>().FindByUserName("someUsername");
答案 0 :(得分:4)
您可以将EnableLazyLoading
的接收方设为约束为IBaseService
的泛型类型。这是罗嗦的,但应该这样做。
public static TService EnableLazyLoading<TService, TEntity, TKey>(this TService service)
where TService : IBaseService<TEntity, TKey>
where TEntity : Entity<TKey>
where TKey : struct
{
// do stuff
return service;
}
这样,您将获得实际的服务类型作为返回类型。我有一段时间没有做过C#,所以我可能会忘记一些重要的事情,但是IIRC这个工作得很好。
答案 1 :(得分:1)
Ben his answer提供的最佳解决方案是:
public static T EnableLazyLoading<T, TEntity, TKey>(
this T @this,
bool enabled)
where T : IBaseService<TEntity, TKey>
where TEntity : Entity<TKey>
where TKey : struct
{
@this.UnitOfWork.EnableLazyLoading(enabled);
@this.UnitOfWork.EnableProxyCreation(enabled);
return @this;
}
另一种解决方案,更便宜但不是那么干净就是使用dynamic
关键字:
public static dynamic EnableLazyLoading<TEntity, TPrimaryKey>(
this IBaseEntityService<TEntity, TPrimaryKey> @this,
bool enabled)
where TEntity : Entity<TPrimaryKey>
where TPrimaryKey : struct
{
@this.UnitOfWork.EnableLazyLoading(enabled);
@this.UnitOfWork.EnableProxyCreation(enabled);
return @this;
}
成本是您失去了IntelliSense的便利性,可能还有一些性能。