.net从抽象类创建对象实例

时间:2011-01-04 11:08:34

标签: c# .net asp.net-mvc

我有以下抽象类:

public abstract class TemplateBase
{
    public abstract string TemplateName { get; }
    public string RuntimeTypeName { get { return GetType().FullName; } }
    public abstract List<AreaContainer> TemplateAreas { get; }
}

然后这两个继承的类:

public class SingleColumnTemplate : TemplateBase
{
    public override string TemplateName { get { return "Single column"; } }

    public AreaContainer CenterColumn { get; private set; }

    public SingleColumnTemplate()
    {
        this.CenterColumn = new AreaContainer("Middle");
    }

    private List<AreaContainer> templateAreas;

    public override List<AreaContainer> TemplateAreas
    {
        get
        {
            if (this.templateAreas == null)
            {
                this.templateAreas = new List<AreaContainer>() { this.CenterColumn };
            }

            return this.templateAreas;
        }
    }
}

public class TwoColumnTemplate : TemplateBase
{
    public override string TemplateName { get { return "Two column"; } }
    public AreaContainer LeftColumn { get; private set; }
    public AreaContainer RightColumn { get; private set; }

    public TwoColumnTemplate()
    {
        LeftColumn = new AreaContainer("Left");
        RightColumn = new AreaContainer("Right");
    }

    private List<AreaContainer> templateAreas;

    public override List<AreaContainer> TemplateAreas
    {
        get
        {
            if (this.templateAreas == null)
            {
                this.templateAreas = new List<AreaContainer>() { this.LeftColumn, this.RightColumn };
            }
            return this.templateAreas;
        }
    }
}

我也有这个类是我的编辑模型:

public class ContentPage
{
    public virtual int ContentPageId { get; set; }

    public virtual string Title { get; set; }

    public TemplateBase Template { get; set; }
}

问题:

对于我的ActionResults我有以下内容:

[HttpGet]
public ActionResult Edit()
{
    var row = new ContentPage();
    var template = new TwoColumnTemplate();        

    // Areas
    HtmlArea html_left = new HtmlArea();
    html_left.HtmlContent = "left area html content";

    HtmlArea html_right = new HtmlArea();
    html_right.HtmlContent = "right area html content";

    template.LeftColumn.Areas.Add(html_left);
    template.RightColumn.Areas.Add(html_right);

    row.Template = template;
    return View(row);
}

[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(ContentPage row)
{
    // Here i could loop through List -TemplateAreas and save each template Area to Db. I guess that would work

    return this.View(row);
}

问题:

对于HttpGet-我如何从数据库中加载行模板?因为它可能是SingleColumnClass或TwoColumnClass。

我的ViewModel将如何解决此问题?

感谢

3 个答案:

答案 0 :(得分:2)

您可以编写自己的Model Binder,负责绑定TemplateBase。您仍然需要知道(在模型绑定器中)您将使用运行时的类型,但您始终可以将其委托给某种类型的工厂或服务定位器。我做了一个快速谷歌搜索,这是一个我发现的博客文章,为您提供了一些信息,为类似的场景制作模型活页夹:

http://weblogs.asp.net/bhaskarghosh/archive/2009/07/08/7143564.aspx

编辑:博客没有告诉你如何告诉MVC你的模型绑定器。应用程序启动时,您可以将模型绑定器添加到System.Web.Mvc.ModelBinders.Binders

HTH

答案 1 :(得分:1)

您需要知道控制器中的模板类型,因此您可以将参数从视图传递到控制器,指示类型(SingleColumnTwoColumn)。您可以通过Enum

执行此操作
public enum TemplateType
{
   SingleColumn,
   TwoColumn
}

[HttpGet]
public ActionResult Edit(TemplateType templateType)
{
    var row = new ContentPage();
    TemplateBase template; 

    if (templateType == TemplateType.SingleColumn)
    {
        template = new SingleColumnTemplate();
    }
    else
    {
        template = new TwoColumnTemplate();
    }

    ...

    return View(row);
}

从视图创建操作链接时,您可以指定:

<%= Html.ActionLink("Edit",
                    "Edit",
                    "YouController",
                    new 
                    { 
                        // singlecolumn or twocolumn
                        // depending on your concrete view
                        TemplateType = TemplateType.xxx 
                    },
                    null); 

答案 2 :(得分:0)

我想知道你是否可以做这样的事情?

[HttpGet]
public ActionResult Edit(TemplateType templateType)
{
    var row = new ContentPage();
    TemplateBase template = (TemplateBase)Activator.CreateInstance(templateType);

    ...

    return View(row);
}

templateType必须是您继承的类的确切名称(您可以忽略大小写)