If WCF is in a MVC application, should it use the

2019-02-19 10:25发布

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?

3条回答
贼婆χ
2楼-- · 2019-02-19 11:02

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
查看更多
该账号已被封号
3楼-- · 2019-02-19 11:08

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

查看更多
狗以群分
4楼-- · 2019-02-19 11:19

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!)

查看更多
登录 后发表回答