Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Custom Model - Where is a simple example?

Tags:

asp.net-mvc

I need to make a web application and I want to use MVC. However, my Model can't be one of the standard Models -- the data is not stored in a database but instead in an external application accessible only via a API. Since this is the first MVC application I've implemented I'm relying on examples to understand how to go about it. I can't find any examples of a non-DB based Model. An example of a custom Model would be fine too. Can anyone point me to such a beast? Maybe MVC is just to new and none exist.

It seems like I might be able to get away with the DataSet Model, however I've not seen any examples of how to use this object. I expect an example of DataSet could help me also. (Maybe it is the same thing?)

Please note: I've seen countless examples of custom bindings. This is NOT what I want. I need an example of a custom Model which is not tied to a specific database/table.

UPDATE

I found a good example from MS located here:

http://msdn.microsoft.com/en-us/library/dd405231.aspx

While this is the "answer" to my question, I don't really like it because it ties me to MS's view of the world. @Aaronaught, @jeroenh, and @tvanfosson give much better answers from a meta perspective of moving my understanding (and yours?) forward with respect to using MVC.

I'm giving the check to @Aaronaught because he actually has example code (which I asked for.) Thanks all and feel free to add even better answers if you have one.

like image 773
Hogan Avatar asked Feb 17 '26 22:02

Hogan


1 Answers

In most cases it shouldn't matter what the backing source is for the actual application data; the model should be exactly the same. In fact, one of the main reasons for using something like a repository is so that you can easily change the underlying storage.

For example, I have an MVC app that uses a lot of web services - rarely does it have access to a local database, except for simple things like authentication and user profiles. A typical model class might look like this:

[DataContract(Namespace = "http://services.acme.com")]
public class Customer
{
    [DataMember(Name = "CustomerID")]
    public Guid ID { get; set; }

    [DataMember(Name = "CustomerName")]
    public string Name { get; set; }
}

Then I will have a repository interface that looks like this:

public interface ICustomerRepository
{
    Customer GetCustomerByID(Guid id);
    IList<Customer> List();
}

The "API" is all encapsulated within the concrete repository:

public class AcmeWSCustomerRepository : ICustomerRepository, IDisposable
{
    private Acme.Services.CrmServiceSoapClient client;

    public AcmeWSCustomerRepository()
        : this(new Acme.Services.CrmServiceSoapClient())

    public AcmeWSCustomerRepository(Acme.Services.CrmServiceSoapClient client)
    {
        if (client == null)
            throw new ArgumentNullException("client");
        this.client = client;
    }

    public void Dispose()
    {
        client.SafeClose();    // Extension method to close WCF proxies
    }

    public Customer GetCustomerByID(Guid id)
    {
        return client.GetCustomerByID(id);
    }

    public IList<Customer> List()
    {
        return client.GetAllCustomers();
    }
}

Then I'll also probably have a local testing repository with just a few customers that reads from something like an XML file:

public class LocalCustomerRepository : ICustomerRepository, IDisposable
{
    private XDocument doc;

    public LocalCustomerRepository(string fileName)
    {
        doc = XDocument.Load(fileName);
    }

    public void Dispose()
    {
    }

    public Customer GetCustomerByID(Guid id)
    {
        return
            (from c in doc.Descendants("Customer")
             select new Customer(c.Element("ID").Value, c.Element("Name").Value))
            .FirstOrDefault();
    }

    // etc.
}

The point I'm trying to make here is, well, this isn't tied to any particular database. One possible source in this case is a WCF service; another is a file on disk. Neither one necessarily has a compatible "model". In this case I've assumed that the WCF service exposes a model that I can map to directly with DataContract attributes, but the Linq-to-XML version is pure API; there is no model, it's all custom mapping.

A really good domain model should actually be completely independent of the true data source. I'm always a bit skeptical when people tell me that a Linq to SQL or Entity Framework model is good enough to use throughout the entire application/site. Very often these simply don't match the "human" model and simply creating a bunch of ViewModel classes isn't necessarily the answer.

In a sense, it's actually better if you're not handed an existing relational model. It forces you to really think about the best domain model for your application, and not necessarily the easiest one to map to some database. So if you don't already have a model from a database - build one! Just use POCO classes and decorate with attributes if necessary, then create repositories or services that map this domain model to/from the API.

like image 184
Aaronaught Avatar answered Feb 21 '26 15:02

Aaronaught