我在尝试使我的架构变得灵活时遇到了类解决问题。为简单起见,请考虑以下示例:
我有四个层:UI,BL,Common和DAL
我的BL层中有一个基类,定义如下:
public class User
{
private UserDTO _d;
public User()
{
_d = new UserDTO();
}
public User(UserDTO d)
{
_d = new UserDTO(d);
}
public UserDTO D
{
get { return _d; }
set { _d = value; }
}
//static method (I cannot make it non-static due to some reasons)
public static User GetUser()
{
User user = new User(Provider.DAL.GetUser());
return user;
}
}
DTO定义为:
public class UserDTO
{
public int ID;
public UserDTO()
{
}
public UserDTO(UserDTO source)
{
ID = source.ID;
}
}
我的DAL被定义为(它返回DTO而不是业务对象):
public static UserDTO GetUser()
{
UserDTO dto = new UserDTO();
dto.ID = 99;
return dto;
}
现在,我想“扩展”我的代码,以便我可以在我的User表中再添加一个字段:Name。所以我创建了一个派生的DTO类:
public class MyUserDTO : UserDTO
{
public string Name;
public MyUserDTO()
{
}
public MyUserDTO(MyUserDTO source)
{
Name = source.Name; //new field
base.ID = source.ID;
}
}
然后,我将派生的User类创建为:
public class MyUser : User
{
public MyUser()
{
this.D = new MyUserDTO();
}
}
我使用此方法创建自己的自定义DAL提供程序:
public static UserDTO GetUser()
{
UserDTO dto = new MyUserDTO();
dto.ID = 99;
((MyUserDTO)dto).Name = "New Provider Name";
return dto;
}
现在,当我在BL中访问此MyUserDTO对象时,它会失去解决方案:
User.GetUser(DAL.Provider.GetUser())
在UI中,我没有在MyUserDTO中获取属性。
是否有一种方法可以帮助我在UI层中获取这些属性,即使在我调用静态User.GetUser()方法之后(它又会调用我的自定义提供程序返回MyUserDTO对象)?
谢谢,
答案 0 :(得分:5)
您不从一个类继承以添加新数据,只有在您的新类将扩展旧类的行为时才继承。
为您的UserDTO提供一个名称 - 值集合来保存其数据并填充该数据。那你就不会有问题了。
答案 1 :(得分:1)
您没有获得派生行为,因为MyUser类无法覆盖用户类中的静态方法。
你应该删除静态方法(我知道你已经指出你不能),但实际上你应该这样做。
尝试在另一个对象(工厂,存储库,...)中提取用户的创建
答案 2 :(得分:1)
正如其他人所提到的,问题在于静态方法。
我还建议使用泛型或依赖注入来清理并行对象层次结构。你不想复制。
不是拥有一组几乎相同的'User'和'MyUser'类,它们具有相同的层次结构,只需执行类似User的操作并插入所需的UserDTO类型。
如果您重构并删除对象层次结构重复,可能会更容易找到一个好的解决方案来解决静态GetUser()的问题。
答案 3 :(得分:0)
从我所看到的内容看起来像User.GetUser()将返回一个User对象,而不是MyUserDTO对象,这就是为什么你没有得到那些额外的字段。 DAL层需要遵守它所针对的合同。有一些方法可以解决这个问题,尽管有些方法比其他方法更“正确”。
您可以将从User.GetUser中获取的对象转换为适当的对象,然后可以访问已转换对象的字段(假设对象可以转换为该类型)。从设计的角度来看,我不太喜欢这个解决方案,但它会起作用:
MyDTOUser myDtoUser = User.GetUser() as MyDTOUser;
其他人已经发布了一些其他方法,所以我不会在这里重复这些。