سؤال

في بلدي ASP.net MVC التطبيق أنا باستخدام طبقة الخدمة والمستودعات للحفاظ على وحدات تحكم بلدي رقيقة. A تفاصيل نموذجية مقروءة عرض فقط يبدو مثل هذا:

public ActionResult Details(int id)
{
    var project = _projectService.GetById(id);

    return View(Mapper.Map<Project, ProjectDetails>(project));
}

وطبقة الخدمة:

public class ProjectService : IProjectService
{
    public Project GetById(int id)
    {
        var project = _projectRepository.GetProject(id);

        // do some stuff

        return project;
    }
}

public class ProjectRepository : IProjectRepository
{
    public Project GetProject(int id)
    {
        return context.Projects.Find(id);
    }
}

والانتقال من طبقة الخدمة لنموذج الرأي السهل جدا بسبب automapper، والتي يمكن تسطيح الأمور بسهولة جدا. نقل مباشر البعض، من طراز بغية تمرير إلى طبقة خدمة بلدي هو المكان الذي يكافح من أجل التوصل إلى حل جيد.

في هذه الحالة كأنه خلق عمل، ما هو نهج جيد لهذا؟

[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    // TODO

    return RedirectToAction("Index");
}

وأنا جدا من أن طبقة الخدمة يجب أن لا يعرف شيئا عن عرض نماذج، لكنني أيضا لا أعتقد أن AutoMapper يعمل بشكل جيد في هذا السيناريو أيضا، لأنها ليست جيدة في أخذ نموذج شقة وجعلها في كائن معقد.

وماذا يجب بلدي تحكم تبدو وكأنها على التواصل مع طبقة الخدمة؟ أريد أن تبقي التعليمات البرمجية في وحدة تحكم ضوء ممكن.

هل كانت مفيدة؟

المحلول

هل يمكن تحديد تعيين ثنائية الاتجاه ثم انتقل على العكس من ذلك:

[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    Project project = Mapper.Map<CreateProjectViewModel, Project>(model);
    // pass the project entity to your service layer
    _projectService.Create(project);

    return RedirectToAction("Index");
}

وأو إذا كنت تقوم بتحديث كيان قد ترغب أول من جلب كيان قائم الذي تريد التحديث من الخدمة:

[HttpPost]
public ActionResult Update(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    Project project = _projectService.GetById(model.Id);
    Mapper.Map<CreateProjectViewModel, Project>(model, project);

    // pass the project entity to your service layer
    _projectService.Update(project);

    return RedirectToAction("Index");
}

نصائح أخرى

والطريقة الوحيدة لقد رأيت هذا القيام به حتى الآن هو خلق مجموعة من الطبقات نموذج التحول يدويا، على سبيل المثال:

public interface ITransformer<out To, in From>
    where To : class
{
    To Transform(From instance);
}

public class SomeDataToSomeViewModelTransformer : ITransformer<SomeViewModel, SomeDataModel>
{
    public SomeViewModel Transform(SomeDataModel instance)
    {
        return new SomeViewModel
            {
                InvitationId = instance.Id,
                Email = instance.EmailAddress,
                GroupId = instance.Group.Id
            };
    }
}

وتنفيذ محول آخر للعودة في الاتجاه الآخر (ViewModel -> DataModel). وجود وحدة تحكم أعرف لاستدعاء محول الصحيح.

وأنا +1 سؤالك لأنني أحب أن أرى وسيلة نظيفة جميلة للقيام بذلك أيضا، دون الحاجة إلى يدويا كتابة مجموعة من التعليمات البرمجية لتعيين النماذج.

إذا طبقة الخدمة الخاص بك هو مخصص فقط لدعم تطبيق MVC ولا يوجد عملاء الأخرى التي يمكن النظر في استخدام الكائنات مرت ومن طبقة الخدمة كجزء من viewmodels الخاص بك. وهذا من شأنه تفادي الحاجة إلى automap يدعو إلى الداخل كما كنت ترسل في الكائنات الفعلية المطلوبة من وحدة تحكم.

هل يمكن أن تنظر أيضا في لا وجود خدمات تعود كائنات المجال، فإن هذا يعني أن automapping يجب التذرع مع أساليب خدمة بدلا من الإجراءات تحكم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top