пятница, 4 июля 2008 г.

Начало реализации

Ну... чего-то мне поднадоело писать требования.
Подожду пока "критиканы" (кстати, мною уважаемые люди, и если кто-то из них обидится на это название, пусть скажет, буду ее вычищать из текста) критикуют и промоют мне мозги по поводу:
- правильности и способа написания use-case,
- определения целей пользователя,
- value-пользователя (ну... это типа подцель или, по другому, какая-то нужная пользователю штука, позволяющая достичь цели),
- и (поверьте) многого другого.
(сегодня был первый день, когда я достиг целей блога, т.е.когда мне с двух сторон приводили доводы и контр-доводы одного и другого и третье и десятого... по поводу описания use-case и требований к сайту.... боюсь я стока сразу усвоить не могу)

Ну так вот, я решил начать описывать структуру БД и пр.
Начнем со структуры базы данных новостей:



Во-от....

Реализация кода:
Если покликать на участках кода в FireFox и IE - код скрывается. (на моих версиях)

Итак! Что бы реализовать работу с Новостями был реализован следующий behind-код. Т.е. тут не приведены файлы представления данных.


Контроллер, обслуживающий новости:
NewsController.cs

  1. using System;
  2. using System.Web.Mvc;
  3. using System.Collections;
  4. using System.Collections.Specialized;
  5.  
  6.  
  7. using NH = VeloLife.NhProxy;
  8. using VeloLife.Models;
  9. using VeloLife.Environment;
  10. using VeloLife.Security;
  11.  
  12. namespace VeloLife.Controllers
  13. {
  14.   /// <summary>
  15.   /// Контроллер "Новостей"
  16.   /// </summary>
  17.   public class NewsController : MyBaseController
  18.   {
  19.     /// <summary>
  20.     /// Отобразить список новостей.
  21.     /// </summary>
  22.     /// <returns></returns>
  23.     public ActionResult List()
  24.     {
  25.       IList result = NH.News.GetActualNewses();
  26.       ViewData["News"] = result;
  27.       return View();
  28.     }    
  29.     
  30.     /// <summary>
  31.     /// Отредактировать новость с ID...
  32.     /// </summary>
  33.     /// <returns></returns>
  34.     [ExternalSecutityCheckAspect(Permission=SecurityContext.PermissionLevel.Administrator)]
  35.     public ActionResult Edit()
  36.     {
  37.       string id = RouteData.Values["id"].ToString().ToLower();
  38.       News news = new News();
  39.       if (id == "")
  40.       {
  41.         news.DateNews = DateTime.Now;
  42.       }
  43.       else
  44.       {
  45.         news.Load(id);
  46.       }
  47.       ViewData["Object"] = news;
  48.       return View();
  49.     }
  50.  
  51.     /// <summary>
  52.     /// Сохранить новость.
  53.     /// </summary>
  54.     /// <returns></returns>
  55.     [ExternalSecutityCheckAspect(Permission = SecurityContext.PermissionLevel.Administrator)]
  56.     public ActionResult Save()
  57.     {
  58.       News news = new News();
  59.       NameValueCollection param = this.Request.Params;
  60.  
  61.       try
  62.       {
  63.         if (param["IdNews"] != "" && param["IdNews"] != "-1")
  64.         {
  65.           news.IdNews = Int32.Parse(param["IdNews"]);
  66.         }
  67.         if (param["DateNews"] == "")
  68.         {
  69.           this.Errors.Add("Не определена дата");
  70.         }
  71.         else
  72.         {
  73.           news.DateNews = DateTime.Parse(param["DateNews"]);
  74.         }
  75.         if (param["CaptionNews"] == "")
  76.         {
  77.           this.Errors.Add("Не определен заголовок");
  78.         }
  79.         else
  80.         {
  81.           news.CaptionNews = param["CaptionNews"];
  82.         }
  83.         if (param["TextNews"] == "")
  84.         {
  85.           this.Errors.Add("Не определено тело новости");
  86.         }
  87.         else
  88.         {
  89.           news.TextNews = param["TextNews"];
  90.         }
  91.  
  92.       }
  93.       catch (Exception e)
  94.       {
  95.         this.Errors.Add("Системная ошибка: " + e.Message);
  96.       }
  97.  
  98.       if (!this.Errors.HasErrors)
  99.       {
  100.         news.Save();
  101.         return null;
  102.       }
  103.       return View("SimpleMessage");
  104. //      return this.RedirectToAction("SimpleMessage", "Main", new { VLServerErrors = this.Errors });
  105.     }
  106.  
  107.     /// <summary>
  108.     /// Спец метод завершения работы с новостями.
  109.     /// Зачем сделал - плохо помню :)
  110.     /// </summary>
  111.     /// <returns></returns>
  112.     [ExternalSecutityCheckAspect(Permission = SecurityContext.PermissionLevel.Administrator)]
  113.     public ActionResult Done()
  114.     {
  115.       return RedirectToAction("List", "News");
  116.     }
  117.   }
  118. }
* This source code was highlighted with Source Code Highlighter.



Автогенереная часть модели:
Model/News.TG.cs

  1. using System;
  2. using NH = VeloLife.NhProxy;
  3.  
  4. namespace VeloLife.Models
  5. {
  6.   public partial class News
  7.   {
  8.     #region Поля
  9.     ///<summary>
  10.     ///Ид новости
  11.     ///</summary>
  12.     private int _IdNews;
  13.     
  14.     ///<summary>
  15.     ///Дата новости
  16.     ///</summary>
  17.     private DateTime _DateNews;
  18.     
  19.     ///<summary>
  20.     ///Заголовок новости
  21.     ///</summary>
  22.     private string _CaptionNews;
  23.     
  24.     ///<summary>
  25.     ///Текст новости
  26.     ///</summary>
  27.     private string _TextNews;
  28.     
  29.     #endregion
  30.     
  31.     #region Свойства доступа к полям
  32.  
  33.     ///<summary>
  34.     ///Обработка Ид новости
  35.     ///</summary>
  36.     public int IdNews
  37.     {
  38.       get
  39.       {
  40.         return _IdNews;
  41.       }
  42.       set
  43.       {
  44.         _IdNews = value;
  45.       }
  46.     }
  47.  
  48.     ///<summary>
  49.     ///Обработка Дата новости
  50.     ///</summary>
  51.     public DateTime DateNews
  52.     {
  53.       get
  54.       {
  55.         return _DateNews;
  56.       }
  57.       set
  58.       {
  59.         _DateNews = value;
  60.       }
  61.     }
  62.  
  63.     ///<summary>
  64.     ///Обработка Заголовок новости
  65.     ///</summary>
  66.     public string CaptionNews
  67.     {
  68.       get
  69.       {
  70.         return _CaptionNews;
  71.       }
  72.       set
  73.       {
  74.         _CaptionNews = value;
  75.       }
  76.     }
  77.  
  78.     ///<summary>
  79.     ///Обработка Текст новости
  80.     ///</summary>
  81.     public string TextNews
  82.     {
  83.       get
  84.       {
  85.         return _TextNews;
  86.       }
  87.       set
  88.       {
  89.         _TextNews = value;
  90.       }
  91.     }
  92.     #endregion
  93.     
  94.     #region Вспомогательные методы по объекту.
  95.  
  96.     ///<summary>
  97.     ///Загрузка объекта
  98.     ///</summary>    
  99.     public void Load(int id)
  100.     {
  101.       using (NH.News db = new NH.News(this))
  102.       {
  103.         db.Load(id);
  104.       }
  105.     }
  106.  
  107.     ///<summary>
  108.     ///Загрузка объекта по ID в виде строки.
  109.     ///часто будет нужна при работе с controller.
  110.     ///</summary>    
  111.     public void Load(string id)
  112.     {
  113.       using (NH.News db = new NH.News(this))
  114.       {
  115.         db.Load(Int32.Parse(id));
  116.       }
  117.     }
  118.     
  119.     ///<summary>
  120.     ///Загрузка объекта
  121.     ///</summary>    
  122.     public void Save()
  123.     {
  124.       using (NH.News db = new NH.News(this))
  125.       {
  126.         db.Save();
  127.       }
  128.     }
  129.     
  130.     #endregion
  131.     
  132.   }
  133. }
  134.  
* This source code was highlighted with Source Code Highlighter.



Custom-реализация модели:
Model/News.Custom.cs

  1. using System.Collections;
  2. using NH = VeloLife.NhProxy;
  3.  
  4. namespace VeloLife.Models
  5. {
  6.   public partial class News
  7.   {
  8.     public News()
  9.     {
  10.       _IdNews = -1;
  11.     }
  12.  
  13.  
  14.  
  15.     public static IList GetActualNewses()
  16.     {
  17.       return NH.News.GetActualNewses();
  18.     }
  19.   }
  20. }
* This source code was highlighted with Source Code Highlighter.



Автогенереная прокси для Nhibernate:
NhProxy/News.TG.cs

  1. using System;
  2. using M = VeloLife.Models;
  3. using NHibernate;
  4. using System.Collections;
  5.  
  6. namespace VeloLife.NhProxy
  7. {
  8.   public partial class News : IDisposable
  9.   {
  10.     ///<summary>
  11.     ///Ссылка на реальный объект
  12.     ///</summary>
  13.     private M.News _realObject;
  14.  
  15.     ///<summary>
  16.     ///Ид новости
  17.     ///</summary>
  18.     private int _IdNews;
  19.     
  20.     ///<summary>
  21.     ///Дата новости
  22.     ///</summary>
  23.     private DateTime _DateNews;
  24.     
  25.     ///<summary>
  26.     ///Заголовок новости
  27.     ///</summary>
  28.     private string _CaptionNews;
  29.     
  30.     ///<summary>
  31.     ///Текст новости
  32.     ///</summary>
  33.     private string _TextNews;
  34.     
  35.  
  36.  
  37.  
  38.     public News()
  39.     {
  40.       _realObject = null;
  41.     }
  42.  
  43.     
  44.     public News(M.News realObject)
  45.     {
  46.       _realObject = realObject;
  47.       IdNews = _realObject.IdNews;
  48.       DateNews = _realObject.DateNews;
  49.       CaptionNews = _realObject.CaptionNews;
  50.       TextNews = _realObject.TextNews;
  51.     }
  52.     
  53.     #region Свойства доступа к полям
  54.  
  55.  
  56.     ///<summary>
  57.     ///Обработка Ид новости
  58.     ///</summary>
  59.     public virtual int IdNews
  60.     {
  61.       get
  62.       {
  63.         return _IdNews;
  64.       }
  65.       set
  66.       {
  67.         _IdNews = value;
  68.       }
  69.     }
  70.  
  71.     ///<summary>
  72.     ///Обработка Дата новости
  73.     ///</summary>
  74.     public virtual DateTime DateNews
  75.     {
  76.       get
  77.       {
  78.         return _DateNews;
  79.       }
  80.       set
  81.       {
  82.         _DateNews = value;
  83.       }
  84.     }
  85.  
  86.     ///<summary>
  87.     ///Обработка Заголовок новости
  88.     ///</summary>
  89.     public virtual string CaptionNews
  90.     {
  91.       get
  92.       {
  93.         return _CaptionNews;
  94.       }
  95.       set
  96.       {
  97.         _CaptionNews = value;
  98.       }
  99.     }
  100.  
  101.     ///<summary>
  102.     ///Обработка Текст новости
  103.     ///</summary>
  104.     public virtual string TextNews
  105.     {
  106.       get
  107.       {
  108.         return _TextNews;
  109.       }
  110.       set
  111.       {
  112.         _TextNews = value;
  113.       }
  114.     }
  115.     private void FillRealObject()
  116.     {
  117.       _realObject.IdNews = IdNews;
  118.       _realObject.DateNews = DateNews;
  119.       _realObject.CaptionNews = CaptionNews;
  120.       _realObject.TextNews = TextNews;
  121.     }
  122.  
  123.  
  124.  
  125.     #endregion
  126.     
  127.     ///<summary>
  128.     ///Загрузка данных по ИД
  129.     ///</summary>    
  130.     public virtual void Load(int id)
  131.     {
  132.       ISession session = NHibernateStorage.GetCurrentSession();
  133.       session.Load(this, id);
  134.       NHibernateStorage.CloseSession();
  135.       FillRealObject();
  136.     }
  137.     
  138.  
  139.     ///<summary>
  140.     ///Сохранение данных.
  141.     ///</summary>    
  142.     public virtual void Save()
  143.     {
  144.       ISession session =null;
  145.       try
  146.       {
  147.         session = NHibernateStorage.GetCurrentSession();
  148.       }
  149.       catch (Exception e)
  150.       {
  151.         throw e;
  152.       }
  153.       ITransaction tx = session.BeginTransaction();
  154.       if (this.IsNew)
  155.       {
  156.         session.Save(this);
  157.       }
  158.       else
  159.       {
  160.         session.Update(this);
  161.       }
  162.       tx.Commit();
  163.  
  164.       NHibernateStorage.CloseSession();
  165.     }
  166.     
  167.     ///<summary>
  168.     ///Проверяет, является ли объект новым.
  169.     ///</summary>    
  170.     protected virtual bool IsNew
  171.     {
  172.       get
  173.       {
  174.         return _realObject.IdNews == -1;
  175.       }
  176.     }
  177.     
  178.     public virtual void Dispose()
  179.     {
  180.      
  181.     }
  182.   
  183.   }
  184. }
* This source code was highlighted with Source Code Highlighter.




Custom-часть прокси для Nhibernate:
NhProxy/News.Custom.cs

  1. using System;
  2. using System.Collections;
  3. using NHibernate;
  4.  
  5. namespace VeloLife.NhProxy
  6. {
  7.   public partial class News
  8.   {
  9.     public static IList GetActualNewses()
  10.     {
  11.       
  12.       ISession session = NHibernateStorage.GetCurrentSession();
  13.       IList result = session.CreateQuery("from News as n where n.DateNews between :minDate and :maxDate")
  14.         .SetDateTime("minDate", DateTime.Now.AddDays(-10))
  15.         .SetDateTime("maxDate", DateTime.Now)
  16.         .List();
  17.       NHibernateStorage.CloseSession();
  18.       return result;
  19.     }
  20.   }
  21. }
* This source code was highlighted with Source Code Highlighter.



Xml-конфиг для Nhibernate:
NhProxy/News.hbm.xml

  1. <?xml version="1.0" encoding="windows-1251" ?>
  2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="VeloLife" namespace="VeloLife.NhProxy">
  3.   <class name="News" table="News">
  4.     <id name="IdNews" column="IdNews">
  5.       <generator class="native" />
  6.     </id>
  7.     <property name="DateNews" column="DateNews" type="DateTime"></property>
  8.     <property name="CaptionNews" column="CaptionNews" type="string"></property>
  9.     <property name="TextNews" column="TextNews" type="string"></property>
  10.   </class>
  11. </hibernate-mapping>
* This source code was highlighted with Source Code Highlighter.



И наконец - шаблон для автогенерации кода:
News.tgd

s template = FullGen.tg

;; Имя объекта
s ObjectName = News

;; Колонки сущности
tdef Fields
cols FieldName = "?", \
FieldType = "?", \
Caption = "?", \
DBName = "?", \
DBType = "?", \
IsPK = "false"

r IdNews, int, "Ид новости"; \
IsPK = true

r DateNews, DateTime, "Дата новости"
r CaptionNews, string, "Заголовок новости"
r TextNews, string, "Текст новости"
tend


Воот... так я больше делать никогда не буду....
Не эффективно...
Но - что-то запихну.
Это - текущая версия. Потом буду упрощать.

Обратите внимания на аттрибуты в контроллере:

[ExternalSecutityCheckAspect(
Permission = SecurityContext.PermissionLevel.Administrator)]


Это Security. Т.е. вызов этого метода произойдет только после полной проверки безопасности.
Это - аспект :)
Но об этом - после. Сегодня мне надоело и я пойду спать.

Комментариев нет: