如果WCF在MVC应用程序中,它是否应该使用控制器访问数据库以保持“DRY”?

发布于 2024-10-18 13:13:50 字数 877 浏览 2 评论 0原文

我有一个访问 SQL 和 Windows Azure 的 MVC 应用程序。逻辑流程如下所示:

Person <--> View <--> Controller.ConvertPersonHere(x) <--> StorageContext.DoDataAction <--> AzurePersonTableEntity

ConvertPersonH​​ere 是 此堆栈的答案溢出问题 它将模型实体转换为存储实体

public class Person
{
    public string Name {get;set;}
    public int ID {get;set;}
}

public class PersonEntity : TableServiceEntity
{
    public string Name {get;set;}
    public int ID {get;set;}

    // Code to set PartitionKey
    // Code to set RowKey
}
  1. 现在我将 WCF 添加到组合中,我应该如何访问数据函数?假设我当前在控制器中有一个 .Save(Person) 方法,并且希望从我的 WCF 调用中Save(Person)

  2. 我需要抽象出控制器中的数据操作吗?

I have an MVC application that accesses SQL and Windows Azure. The logical flow looks like this:

Person <--> View <--> Controller.ConvertPersonHere(x) <--> StorageContext.DoDataAction <--> AzurePersonTableEntity

ConvertPersonHere is the answer to this Stack Overflow question and it converts the Model entity to the Storage entity

public class Person
{
    public string Name {get;set;}
    public int ID {get;set;}
}

public class PersonEntity : TableServiceEntity
{
    public string Name {get;set;}
    public int ID {get;set;}

    // Code to set PartitionKey
    // Code to set RowKey
}
  1. Now that I'm adding WCF to the mix, how should I go about accessing data functions? Assume I have currently have a method to .Save(Person) in the controller and want to Save(Person) from my WCF call.

  2. Do I need to abstract out the data actions in the controller?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

却一份温柔 2024-10-25 13:13:51

我知道这是一个切线,但如果您混合使用 WCF 和 ASP.NET MVC,您至少应该了解 OpenRasta主要贡献者的 Herding Code 播客是一个好的开始。

(不,这甚至不是为了回答您的实际问题!)

I know it's a tangent, but if you're mixing WCF and ASP.NET MVC, you should at least be aware of OpenRasta. A good start is this Herding Code podcast with the main contributor.

(No, this is not even intended to answer your actual question!)

Bonjour°[大白 2024-10-25 13:13:50

我会像这样重构代码 - 将功能从 Person 转换为 PersonEntity,反之亦然到单独的映射器,将保存功能也移动到单独的存储库,并将用于调用映射器和存储库的控制器代码也移动到单独的服务。
因此,控制器中的方法将类似于:

public ActionResult SomeMethod(Person person)
{
    if (ModelState.IsValid)
    {
        _personService.Save(person)
        return View("Success");
    }
    return View();
}

在 WCF 服务中,您将能够重用代码。为了使用 DataAnnotations 属性验证 WCF 中的类,您可以使用类似于以下的方法 - http://blog.jorgef.net/2011/01/odata-dataannotations.html

I would refactor the code like this - move the functionality to convert from Person to PersonEntity and vice versa to a separate mapper, move saving functionality to separate repository as well, and move controller's code for invoking mapper and repository to separate service too.
So methods in your controller will look similar to:

public ActionResult SomeMethod(Person person)
{
    if (ModelState.IsValid)
    {
        _personService.Save(person)
        return View("Success");
    }
    return View();
}

And in your WCF service you'll be able to reuse the code. In order to validate the classes in WCF using DataAnnotations attributes, you can use the approach similar to the following - http://blog.jorgef.net/2011/01/odata-dataannotations.html

红颜悴 2024-10-25 13:13:50

在此示例中,如果您的 Mvc 项目已消失并被 Wpf 项目取代,您的其他功能仍然可用。如果您有这两个项目,它们可以引用核心功能。在其他项目中有与UI(MVC或WPF)无关的实现。这样那些 UI 项目就可以引用此功能。

public interface IConverter<TDataModel, TModel> { TModel MapToDomain(TDataModel source);}
public interface IPersonConverter : IConverter<PersonEntity, Person> { }
public interface IPersonRepository { Person GetById(int id); }

public class PersonConverter : IPersonConverter
{
    public Person MapToDomain(PersonEntity source)
    {
        return new Person { ID = source.ID, Name = source.Name };
        //or use an AutoMapper implementation   
    }
}

public class PersonRepository : IPersonRepository
{
    private readonly IPersonConverter _personConverter;

    public PersonRepository(IPersonConverter personConverter)
    {
        _personConverter = personConverter;
    }

    public Person GetById(int id)
    {
        PersonEntity personEntity = new PersonEntity(); //get from storage
        return _personConverter.MapToDomain(personEntity);
    }
}

public class MvcController
{
    private readonly IPersonRepository _personRepository;

    public MvcController(PersonRepository personRepository)
    {
        _personRepository = personRepository;
    }

    public ActionResult SomeMethod(int id)
    {
        Person person = _personRepository.GetById(id);

        //make your view model based on the person domain model
        //with another convert / map, to fit view as personForm
        //(if this is overkill you can use person).

        return View(personForm);
    }
}

Mvc或Wpf项目

  • PersonForm(ui模型)
  • Controller或Wpf类
  • Person -> PersonForm 转换器
  • 列表项

核心项目

  • Person
  • IPersonRepository

基础设施项目

  • 人员存储库
  • 人员实体
  • Azure 人员表实体
  • 存储上下文

From this example, if your Mvc project was gone and replaced by a Wpf project, your other functionality is still available. If you have both projects they can reference core functionality. Have the implementation which has no relation to UI (MVC or WPF) in other projects. This way those UI projects can reference this functionality.

public interface IConverter<TDataModel, TModel> { TModel MapToDomain(TDataModel source);}
public interface IPersonConverter : IConverter<PersonEntity, Person> { }
public interface IPersonRepository { Person GetById(int id); }

public class PersonConverter : IPersonConverter
{
    public Person MapToDomain(PersonEntity source)
    {
        return new Person { ID = source.ID, Name = source.Name };
        //or use an AutoMapper implementation   
    }
}

public class PersonRepository : IPersonRepository
{
    private readonly IPersonConverter _personConverter;

    public PersonRepository(IPersonConverter personConverter)
    {
        _personConverter = personConverter;
    }

    public Person GetById(int id)
    {
        PersonEntity personEntity = new PersonEntity(); //get from storage
        return _personConverter.MapToDomain(personEntity);
    }
}

public class MvcController
{
    private readonly IPersonRepository _personRepository;

    public MvcController(PersonRepository personRepository)
    {
        _personRepository = personRepository;
    }

    public ActionResult SomeMethod(int id)
    {
        Person person = _personRepository.GetById(id);

        //make your view model based on the person domain model
        //with another convert / map, to fit view as personForm
        //(if this is overkill you can use person).

        return View(personForm);
    }
}

Mvc or Wpf project

  • PersonForm (ui model)
  • Controller or Wpf Class
  • Person -> PersonForm converter
  • List item

Core project

  • Person
  • IPersonRepository

Infrastructure project

  • Person Repository
  • Person Entity
  • Azure Person Table Entity
  • Storage Context
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文