2011-01-04 6 views
2

У меня есть следующий абстрактный класс:.net создать экземпляр объекта от абстрактного класса

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

то эти 2 наследственные классы:

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 будет выглядеть так, чтобы решить эту проблему?

благодарит

ответ

1

Вы должны знать тип шаблона в вас контроллер, так что вы можете передать параметр из представления к контроллеру, с указанием типа (SingleColumn или TwoColumn). Вы можете сделать это WITN 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); 
+0

Вот что я пытаюсь avoid..the, если другого заявления. Я знаю, какой тип TemplateBase принадлежит: public string RuntimeTypeName {get {return GetType(). FullName; }} Что бы мой объект db выглядел? и как он будет загружаться в ContentPage без использования if/else. Может быть, использовать GetType()? Я нашел это: http: //www.yoda.arachsys.com/csharp/plugin.html, но я не уверен, как его реализовать. – ShaneKm

+0

@ Шейн: Извините, не могли бы вы лучше объяснить? –

+0

Хорошо, я думаю, что в моем ActionResult для HTTPPost у меня было бы следующее: [HttpPost] [ValidateInput (false)] public ActionResult Edit (строка ContentPage) { // Я могу получить список здесь; foreach (элемент var в TemplateAreas) {// Сохранение каждой области ...}; Сохранить 'row' return this.View (row); } проблема HTTPGET. Как бы я загрузил абстрактный класс ContentPage? без выполнения if/else. спасибо – ShaneKm

0

Интересно, если вы могли бы сделать что-то вроде этого?

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

    ... 

    return View(row); 
} 

templateType должен быть точным именем вашего унаследованных классов (вы можете игнорировать регистр)

+0

см. Мой последний ответ – ShaneKm

2

Вы можете написать свою собственную модель Binder, который отвечает за связывание TemplateBase. Вы все равно должны иметь способ узнать (в привязке к модели), какой тип вы будете использовать во время выполнения, но вы всегда можете делегировать это на какой-либо фабричный или сервисный локатор. Я сделал быстрый поиск Google и здесь в блоге я обнаружил, что дает некоторую информацию для создания модели связующего для подобного сценария:

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

EDIT: В блоге выходит, как вы говорите MVC о вашем модель связующего. При запуске приложения, вы можете добавить модель связующего вещества System.Web.Mvc.ModelBinders.Binders

HTH

Смежные вопросы