简短:我正在创建一个MVC应用程序,我需要在其中显示各种类型的文档,其中一些包含比其他文档更多的作者信息。
我想做什么:我的方法是拥有一个通用的"查看文档" view,以传递给它的对象的形状/类型指示的格式动态显示文档。
示例:一个简单的文档将被加载到SimpleDocumentViewModel中,并显示为这样。但是,我想将更大类型的文档加载到ExtendedDocumentViewModel中,并带来有关文档和作者的其他信息。然后,视图将根据它接收的对象显示适当的数据。
我现在所处的位置:在这种情况下,我已经创建了以下界面和类,但我仍然坚持如何返回/识别更多派生类中的特定返回类型。
abstract class BaseDocumentViewModel : DocumentViewModel, IDocumentViewModel
{
public int DocumentId { get; set; }
public string Body { get; set; }
public IAuthorViewModel Author { get; set; }
}
class SimpleDocumentViewModel : BaseDocumentViewModel
{
}
class ExtendedDocumentViewModel : BaseDocumentViewModel
{
public new IAuthorExtendedViewModel Author { get; set; }
}
interface IAuthorViewModel
{
int PersonId { get; set; }
string Name { get; set; }
}
interface IAuthorExtendedViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
}
问题:所以我的问题是;我如何才能从完全实现的类中获取特定类型,或者我是否需要返回基类型并在视图中查询所有类型?或者我是不是想要回到绘图板上了?
编辑:
我知道c# doesn't support return type covarience,但希望可能有另一种方式来返回/识别派生类型,这样我就不必在视图中查询它们了。
我当前的解决方案是始终返回基类型,并为每个具体类型提供单独的视图,只需将每个对象转换为正确的类型,只查询可能不同的对象。也许这是最好的解决方案,但感觉非常不优雅。
答案 0 :(得分:1)
@if(Model is ExtendedDocumentViewModel)
{
// render ExtendedDocumentViewModel html here
}
类型检查通常被认为是反模式,但我不确定是否有更好的方法来解决这个问题。如果您使用的是.NET Core,还可以在此处检查子类标记http://examples.aspnetcore.mvc-controls.com/InputExamples/SubClass。
答案 1 :(得分:0)
可能的清除选项是在每个文档必须实现的名为GetView的接口中有一个签名。这样每种文档类型都有自己实现函数的方式,调用函数知道每个文档都有一个函数GetView。如果每个文档都有一种查看文档的独特方式,则此方法可以正常工作。但是,如果某些文档以相同的方式获取视图,那么我是否可以建议将每个View类型创建到自己的类中,并且可以将视图类型分配给每个文档。我建议调查策略模式。
第一个建议:
class SimpleDocumentViewModel : IAuthorViewModel
{
view GetView()
{
... do document specific stuff
... return view
}
}
class ExtendedDocumentViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
view GetView()
{
... do document specific stuff
... return view
}
}
interface IAuthorViewModel
{
view GetView();
}
第二个建议:
class SimpleDocumentViewModel : IAuthorViewModel
{
public viewType1 view {get;set;}
public SimpleDocumentViewModel(viewType1 viewIn,etc...)
{
view = viewIn;
}
view GetView()
{
return view.GetView();
}
}
class ExtendedDocumentViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
public viewType2 view {get;set;}
public ExtendedDocumentViewModel(viewType2 viewIn,etc...)
{
view = viewIn;
}
view GetView()
{
return view.GetView(ExtraData,MoreExtraData);
}
}
interface IAuthorViewModel
{
view GetView();
}
答案 2 :(得分:0)
我可能会离开这里,但正如我理解你的问题...为什么不把对象中的返回类型抛出并传递给你的视图?
您可以查看所需的方法并使用反射来提取您想要的任何信息。修改它,对象类保存你想要的任何内容。
public class DiscoverInternalClass
{
public List<InternalClassObject> FindClassMethods(Type type)
{
List<InternalClassObject> MethodList = new List<InternalClassObject>();
MethodInfo[] methodInfo = type.GetMethods();
foreach (MethodInfo m in methodInfo)
{
List<string> propTypeList = new List<string>();
List<string> propNameList = new List<string>();
string returntype = m.ReturnType.ToString();
foreach (var x in m.GetParameters())
{
propTypeList.Add(x.ParameterType.Name);
propNameList.Add(x.Name);
}
InternalClassObject ICO = new InternalClassObject(c.Name, propNameList, propTypeList);
MethodList.Add(ICO);
}
return MethodList;
}
}
对象类可能是这样的,或者根据需要修改它:
public class InternalClassObject
{
public string Name { get; set; }
public List<string> ParameterNameList { get; set; }
public List<string> ParameterList { get; set; }
public InternalClassObject(string iName,List<string> iParameterNameList, List<string> iParameterList)
{
Name = iName;
ParameterNameList = iParameterNameList;
ParameterList = iParameterList;
}
}
您可以使用所需的类调用此方法。
public static List<InternalClassObject> MethodList = new List<InternalClassObject>();
DiscoverInternalClass newDiscover= new DiscoverInternalClass();
MethodList = newDiscover.FindClassMethods(typeof(ExtendedDocumentViewModel));
现在,您可以根据MethodList
中的内容构建GetView希望这有帮助!