Design for multi-tenant app using SOA, UoW, Reposi

2020-07-25 03:34发布

问题:

Let me start by apologizing for the length of this post but I wanted to provide as much detail as possible to increase the chance of an answer. Thanks in advance.

I’m adding new features to an existing application that integrates data from several databases. In short, it allows clients and/or their accountants to access and update financial information about their locations. The application has 3 tiers with a web client (I’m looking to replace this will a Silverlight client very soon), a service layer running on an app server and the database tier.

When I took ownership, the application, despite having 3-tiers, was very simplistic. It is using ADO.NET for everything and the web service is simply a pass-through for dynamic (string) SQL queries on one of the databases. My first task was to “clean-up” the existing code. There was nothing object-oriented about the app and everything was flat. I’ve begun refactoring the application to leverage LINQ-to-SQL, implemented the Repository pattern to make the business logic testable (not to mention more maintainable as we evolve the data access technology from ADO.NET to L2S and, hopefully, on to Entity Framework) and reworked the code to actually use the features of .NET.

For the most part, the web app is a piece of cake as every page is a simple query on a table or view in the database (via the web service). On the app server side, I ended up with a DataContext for each database and a Repository for each entity (or Aggregate Root using DDD terms). I use constructor injection (Castle Windsor) to set the proper repository instance for my service class and likewise for the DataContext used by the repository.

This is all well and good except now I have to add edit capability into the application that requires logic spanning 4 databases and I’m at a loss for the right approach. It is critical that the flow and architecture of the app is consistent and maintainable by junior-grade developers. (Aside from me, the team is basically VB6 devs who think they are programming .NET because they are using VS and the BCL – they know very little about patterns, practices, unit testing, mocking, etc, etc, etc) 

Let me walk through what is needed to make the edit view work:

  1. When the page is first loaded, I generate a list of “editable” fiscal periods.
    1. This list is based on a set of rules contained in a SQL Server database (call it the “Metadata” db). Each row in the table identifies the fiscal period by name along with the timeframe it may be edited.
    2. These rules are used to query a table in the DB2 financial database that maps the period name and year to the actual dates. This query will return all entries with an end date in the past and a close date (end date plus edit length from above) after today.
  2. The page will default the selected period to the most recent. When a period is selected, I fire another request to populate a list of locations that the current user may edit during the selected period.
    1. First I have to interrogate the user’s security information from the “Security” database and determine if they are in the Accountants role. If so, then I have to query the Metadata database to retrieve a list of clients for the current user. If not, then I use the clientID of the current user.
    2. Next I query the DB2 financial database to obtain the list of locations, filtering based on the selected period and list of clientIDs that the user may access. I also filter based on the status so I only return locations that were active during that period.
  3. As with the period, the page will default the selected location to the first one in the list. When the location is selected, I make another request for the actual financial data for that location during the selected period.
    1. This request is made to the “Staging” database and is pretty straight-forward.
  4. All of this repeats if the user selects a different period or location.

So, let’s take #2 and walk through how I should be implementing this in my service application using the Unit Of Work and Repository patterns and… Oh, one problem – there is no LINQ-to-DB2 and the company won’t make the jump to EF yet so I am left with using ADO.NET when working with that database. But don’t let that hold you up as I’d like a solution that is as data access tech-agnostic as possible because they could change their minds any day. In fact, they could shift paradigms and go to NHibernate for all I know at this point. I’m more concerned with getting from the service façade to the DataContext and not so much about how the DataContext (or ObjectContext) is implemented.

Can you walk me through the implementation of calling my web service method with the current user’s credentials and selected fiscal period, performing the steps outlined in #2 above and returning the appropriate list of locations?

Whew… That was a lot to take in. I appreciate the help sorting it out.