Реализуйте метод Save для моего объекта

Я пытаюсь улучшить дизайн своего приложения, поэтому вместо вызова уровня DataAccess из уровня представления. Я попытаюсь реализовать метод сохранения из моего объекта в слое BusinessObjects. но я не уверен, как передать объект или его свойства через слои. например, в моем старом проекте я просто создаю экземпляр моего объекта на уровне представления и назначаю его свойства, затем просто вызываю метод DataAccess для сохранения этой информации в базе данных и передаю объект в качестве параметра, как показано на рисунке.

DAL

public static void SaveObject(Object obj)
{
   int id = obj.id;
   string label = obj.label;
}

PL

Object obj = new Object();
obj.id = 1;
obj.label = "test";
DAL.SaveObject(obj); 

но я просто хочу сделать это в моем PL

Object obj = new Object();
obj.id = 1;
obj.label = "test";
obj.SaveObject();

Это возможно? и как будет выглядеть мой DAL?

Изменить: объясняя мои требования

Я сейчас основываю свой код на очень важном объекте в моей системе.

BusinessEntitiesLayer использует BusinessLogic Layer

namespace BO.Cruises
{
    public class Cruise
    {
        public int ID
        { get; set; }

        public string Name
        { get; set; }

        public int BrandID
        { get; set; }

        public int ClassID
        { get; set; }

        public int CountryID
        { get; set; }

        public string ProfilePic
        { get; set; }

        public bool Hide
        { get; set; }

        public string Description
        { get; set; }

        public int OfficialRate
        { get; set; }

        public string DeckPlanPic
        { get; set; }

        public string CabinsLayoutPic
        { get; set; }

        public List<Itinerary> Itineraries
        { get; set; }

        public List<StatisticFact> Statistics
        { get; set; }

        public List<CabinRoomType> RoomTypesQuantities
        { get; set; }

        public List<CabinFeature> CabinFeatures
        { get; set; }

        public List<CruiseAmenity> Amenities
        { get; set; }

        public List<CruiseService> Services
        { get; set; }

        public List<CruiseEntertainment> Entertainment
        { get; set; }

        public List<CustomerReview> CustomerReviews
        { get; set; }
    }

}

BusinessLogicLayer использует DataAccessLayer

На самом деле этот слой предназначен для проверки моего объекта, а затем для вызова методов DAL, но я не выполнял никакой проверки прямо сейчас, поэтому я просто использую его для вызова методов DAL.

    public static void Save(object cruise)
    {
        CruisesDAL.Save(cruise);
    }

DataAccessLayer пытается сослаться на BussinessEntities, но выдает ошибку циклических зависимостей!

Он должен получить объект и разыграть его как сущность Круиза.

    public static void Save(object cruise)
    {
         Cruise c = cruise as Cruise;

         //access the object c properties and save them to the database
    }

Пример кода из моего проекта:

public static List<Cruise> GetCruisesList()
{
    string commandText = "SELECT ID, Name + CASE Hide WHEN 1 Then ' (Hidden)' ELSE '' END AS Name FROM Cruises";
    List<Cruise> cruises = new List<Cruise>();
    Cruise cruise;

    using (SqlConnection connection = new SqlConnection(ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(commandText, connection))
        {
            connection.Open();

            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    cruise = new Cruise();

                    cruise.ID = Convert.ToInt32(reader["ID"]);
                    cruise.Name = reader["Name"].ToString();

                    cruises.Add(cruise);
                }
            }
        }
    }

    return cruises;
}

PresentationLayer использует BusinessEntities

Элементы управления вводом (TextBoxes, DropDownList и т. Д.)

Когда нажата кнопка сохранения, я беру все значения, создаю объект Cruise и вызываю Cruise.Save();

3 ответа

Решение

Передача самого объекта на уровень данных, как правило, немного прикольная. Вместо этого я рекомендую, чтобы объект осуществлял связь со слоем данных, и пусть слой данных делает свое дело.

internal static class DataLayer {

    public static bool Update(int id, string label) {
        // Update your data tier
        return success; // bool whether it succeeded or not
    }
}

internal class BusinessObject {

    public int ID {
        get;
        private set;
    } 

    public string Label {
        get;
        set;
    } 

    public bool Save() {
        return DataLayer.Update(this.ID, this.Label); // return data layer success
    }
}

Причина, по которой вы будете делать это таким образом, заключается в том, что ваш уровень данных может не иметь ссылку на ваш бизнес-объект и, следовательно, не будет иметь понятия, что это такое. Вы не сможете пройти сам объект. Это обычный сценарий, потому что обычно это сборка вашего бизнес-объекта, которая ссылается на вашу сборку уровня данных.

Если у вас все в одной сборке, то вышеупомянутое не применимо. Позже, однако, если вы решите реорганизовать свой слой данных в его собственный модуль (что часто и получается, и это хороший дизайн), передача объекта будет нарушена, потому что тогда он потеряет свою ссылку на ваш бизнес-объект.

В любом случае, вы должны знать, что вам придется обновлять как ваш объект, так и слой данных, если вы добавите новое поле или элемент. Это просто дано, когда вы добавляете что-то новое.

Я могу написать блог о некоторых хороших методах дизайна для этого, но это моя рекомендация.

Вы должны избегать смешения модели предметной области с логикой постоянства. Примеры, приведенные выше, позволили бы получить решение с жестким сцеплением. Для достижения.SaveObject() вы можете создать в BL методы расширения, которые бы выполняли эту работу.

BL. *

public static class ObjectPersistanceExtensions{

       public static SaveObejct<T>(this IBaseEntity obj){

            IObjectDal<T> _dal = AvailableSerices.Obtain<IObjectDal<T>>();
            _dal.AddObject(obj);
            _dal.Commit();
       }
}

Таким образом, таким образом вы все еще можете добавить функционеров к объектам домена, не связывая логику в объектах домена.

Если вы будете следовать этому шаблону, у вас будет логика сохранения внутри самого определения объекта, поэтому при вызове из PL:

obj.SaveObject();

это произойдет в самом объекте:

public void SaveObject()
{
  DAL.SaveObject(this);
}

и ваш DAL остается таким же, как показано выше.

это вопрос дизайна, я бы не стал использовать логику сохранения внутри объекта, но у меня был бы BusinessManager или ObjectMapper для чтения из DAL и сохранения в DAL.

в общем случае рекомендуется читать или загружать и сохранять в одном и том же месте, BusinessObject или BusinessManager, но вместе, чтобы вы могли легко найти их и быстро обновить как при добавлении, так и при изменении поля.

Другие вопросы по тегам