views:

51

answers:

2

I'm looking for a bit of guidance on the architecture of an application I'm creating. Here is the situation:

Our company gives out reward cards to salesmen which are then handed out to customers (used like a debit card). For tracking purposes, the salesman must request activation from our system before the card can be used (providing information on who they gave the card to and why). The front-facing app is ASP.NET MVC 2. A windows service will periodically check for activation requests and call a web service from the company that issued the card (there is really two card companies and two services involved) to activate it. Then it marks the status of the card as activated in the DB.

My solution is split into 5 projects: Web, Data (model and repository), CompanyClients (access to the two web services), Service (windows service), and Tests.

As things currently stand, some code to go in the windows service might look like this:

using (var repo = new Repository())
{
    var cards = repo.GetAllPendingCardsWithOrderAndCompany();

    foreach (var card in cards)
    {
        var client = CompanyClientFactory.GetClient(card);

        try
        {
            client.ActivateCard(card);
            card.ActivationDt = DateTime.Now;
        }
        catch(Exception ex)
        {
            // Error logging goes here
        }
    }
    repo.Save();
}

This works, but I can't help thinking of the issue of Anemic Domain Model. Should I add a method to Card called Activate() which gets the web service client and tries the real activation and logging itself? This would make the windows service much cleaner:

using (var repo = new Repository())
{
    var cards = repo.GetAllPendingCardsWithOrderAndCompany();

    foreach (var card in cards)
    {
        card.Activate();
    }
    repo.Save();
}

However, this would require the Data project to reference CompanyClients. CompanyClients itself already references Data so this would create a circular dependency. I could lump the two projects together, but that doesn't feel right to me (as it is, I'd like to eventually go to POCO and split up the model and data access to different projects).

Any thoughts on a better way to organize this?

A: 

Yeah, I understand your problem, you are asking if it is ok to put the dataccess methods on Model classes or leave it at Clients, which is a project that contains methods to access the web services.

I had similar thoughts myself on similar project and I decided to keep Model classes very simple, they actually don't have any methods, only properties.

Also, the notion of Client making connections to the web services also doesn't feel right. The Client should also go into Models project. The code that you use now to connect to webservices should be moved to a separate project called WebServiceProxy or something like that.

This project should follow the Repository/Service pattern. The linked article actually discusses the repository pattern in connection with webservices (besides the usual Repository to DB stuff).

HTH

mare
Thanks. I do currently have a proxy class implementing an interface which the client accesses. I put the client into the same project as the proxy so my domain wouldn't have to deal with the auto-generated typed datasets, but you may be right that it should be together.
InvidFlower
A: 

In the end, the answer of whether to have the call from inside or outside the Card class came from thinking more deeply about it from an OO perspective. While it seems nice at first glance to group that functionality together, it makes no sense for a card to activate itself. So in any case, that belongs outside of the Card class.

As for issue of how to separate out to various projects, I think this answer makes sense, which uses a Separate Interface, for which there is a great tutorial: Refactoring Service Dependencies to Separated Interface.

InvidFlower