我想删除GetById
和Map
方法中的switch case块,以提高代码可读性,并简化.NET核心应用程序中的编码实践。
public enum IdentityProviderType
{
Okta = 0,
Ping = 1,
Internal = 2
}
public async Task<UserResponseDTO> GetById(string id)
{
IdentityProviderType provider = //custom logic to retrieve IdentityProviderType enum
object idpUser = null;
switch (provider)
{
case IdentityProviderType.Okta:
idpUser = await _oktaUserService.GetById(id);
break;
case IdentityProviderType.Ping:
idpUser = await _pingUserService.GetById(id);
break;
case IdentityProviderType.Internal:
idpUser = await _internalUserService.GetById(id);
break;
}
return _mapUserService.Map(idpUser);
}
public class MapUserService
{
public UserResponseDTO Map(IdentityProviderType provider, object idpUser)
{
switch (provider)
{
case IdentityProviderType.Okta:
var oktaUser = (OktaUser)idpUser;
//Map OktaUser fields to UserResponseDTO fields
break;
case IdentityProviderType.Ping:
var pingUser = (PingUser)idpUser;
//Map PingUser fields to UserResponseDTO fields
break;
case IdentityProviderType.Internal:
var internalUser = (InternalUser)idpUser;
//Map InternalUser fields to UserResponseDTO fields
break;
}
}
}
从互联网上关于同一主题的不同资源中,我得出了可能的想法,但不确定如何实现它,因为我有不同的对象OktaUser/PingUser/InternalUser。
我开始创造一些
public abstract class IdpUserService
{
public abstract object GetById(string id);
}
但不确定如何完成它,我应该使用T或对象作为输出吗?
任何帮助如何重构和摆脱开关情况将是有帮助的。
4条答案
按热度按时间hvvq6cgz1#
下面是可以帮助您的完整代码。
首先,您需要为方法
GetById
抽象IdpUserService
。此外,您还需要抽象
IdpUser
并将方法Map
移到其中。现在您可以实现
IdpUserService
的特定版本。类似地,您将需要实现
IdpUser
的特定版本以从特定服务类返回。现在您有了
IdpUserService
的多个实现,您希望使用枚举IdentityProviderType
从中选择一个。我们将使用依赖注入来构造对象。因此,我们将把所有服务注册到DI容器。并且创建一个类
NamedImpl
来将服务Map到特定的IdentityProviderType
。现在,为了获取特定的
IdpUserService
,我们将创建一个工厂类,通过构造函数获取所有已注册IdpUserService类型的列表。以及一个get方法,获取IdentityProviderType
作为参数,并返回IdentityProviderType
所提供参数的特定实现的IdpUserService
。现在,您所发布的代码的问题,可以结构如下,以利用所有的变化,我们已经做了以上。
我知道这看起来太复杂了,但是这样你的代码将是非常可扩展的,因为你正在为同一类型的服务使用许多实现。
针对
NamedImpl
的实施vuktfyat2#
也许只有一个具有不同属性的用户对象,而不是
OktaUser
、PingUser
和InternalUser
?k0pti3hp3#
如果不全面了解代码库,很难选择最佳选项,根据所提供的代码,最佳选项似乎是抽象
IdpUserService
,这样它将返回UserResponseDTO
,并在具体的服务实现中处理转换:如果有部分代码需要使用“原始”用户,则为每个类型创建Map方法(扩展方法或作为
%SourceName%User
类型的一部分):fv2wmkja4#
大概是这样的