Referenceing Projects

G

Guest

Hello All:

I have a solution with four projects (UI, Business, Database and Messaging).
UI has references to Business and Messaging; Business has a refernce to
Database; Messaging has a reference to Business. UI handles the
presentation; Business provides Presentation with an abstract layer through
which to retrieve data; Database handles database calls. Messaging handles
calls to a third-party system; it is similar to Database.

I do not have the option of combining Databbase and Messaging; I need to
retain this architecture (client requirement).

What I want to do is provide a way for Business to call Messaging so that I
can continue to abstract how or where data comes from. (UI doesn't need to
know where information comes from.)

It was suggested in a previous post that I create a third project (ref'd by
both Business and Messaging) that defines abstact classes and allow the
Business project to implement these.

Does anyone know of an online example showing how to do this? Could someone
provide a simple example of how this works or what it would look like? I
don't have a lot of time (maybe a week) and have limited experience
implementing such solutions.

TIA,
 
K

Kevin Spencer

Hi Joe,

It seems to me that your current model has a fatal flaw. You say that
Messaging is similar to Database. By this, I believe you mean that it is a
layer unto itself that provides Messaging capabilities and is therefore,
like Database, re-usable. But it is dependent upon the Business class.

A Business class should provide business logic for a specific set of data.No
lower-tier objects should be dependent upon it.

Now, the way we handle this sort of thing is to have an assembly that
provides data and functionality that is globally available to any class in
any assembly in any NameSpace. This assembly (and the NameSpaces in it)
functions much like the mscorlib or System assembly in the CLR. It is
composed of logging capabilities, utility functions, and a number of other
globally-useful classes and members that can be used by any assembly. It has
no external dependencies, other than the CLR.

When we create a new project for a specific purpose, we design business
classes that use the members of this assembly for this type of thing. And
our Data classes also use this assembly. In your case, your Messaging
classes could use a similar assembly. This way, the Business classes could
be dependent upon the Messaging as well as the Data classes.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Complex things are made up of
Lots of simple things.
 
G

Guest

Hi Kevin,

Thank you so much for your reply. I can not break the reference to the
Business project that the Messaging project has. Please read on.

This company has two data sources. The Messaging project contains classes
that retrieve data from the third-party system (via XML). The Database
project contains classes that retrieve data from the company's home-grown
databases. They both have the same purpose: to retrieve data, but they
retrieve data from different sources in different ways.

The Messaging project references the Business project because its methods
use classes that are in the Business project (for eample, Vehicle,
CommercialUnit, Policy). The Business project classes have data retrieved
from the company's home-grown databases and now need to retrieve data from
the third-party databases. That's why the Business objects are passed to the
Messaging classes; they contain information that the Messaging classes use to
retrieve data.

I agree with you: a Business class should provide business logic for a
certain set of data. I, however, have no control over the initial design of
this solution. The developers who built this solution designed it this way
because they wanted the Messaging classes to be able to receive a business
object (say a Vehicle object with info about a certain vehicle); the reason
that they did this is because a Vehicle has a ton of information connected
with it and they didn't want to have to pass 40 parameters to a Messaging
method call when they can jsut pass one object.

What I am trying to do is find a way to excapsulate data calls, so that when
I ask for a piece of information regarding a Vehicle (for example), the
Business class will retrieve what I request from either the hown-grown system
or the third-party system whichever is appropriate. The problem is that I
can not reference the Messaging project from the Business project because
that would create a circular reference.

What do you think? Still the same idea? Another?
--
Joe

VB.NET/C#/ASP.NET/ASP/VB/C++/Web and DB development/VBA Automation


Kevin Spencer said:
Hi Joe,

It seems to me that your current model has a fatal flaw. You say that
Messaging is similar to Database. By this, I believe you mean that it is a
layer unto itself that provides Messaging capabilities and is therefore,
like Database, re-usable. But it is dependent upon the Business class.

A Business class should provide business logic for a specific set of data.No
lower-tier objects should be dependent upon it.

Now, the way we handle this sort of thing is to have an assembly that
provides data and functionality that is globally available to any class in
any assembly in any NameSpace. This assembly (and the NameSpaces in it)
functions much like the mscorlib or System assembly in the CLR. It is
composed of logging capabilities, utility functions, and a number of other
globally-useful classes and members that can be used by any assembly. It has
no external dependencies, other than the CLR.

When we create a new project for a specific purpose, we design business
classes that use the members of this assembly for this type of thing. And
our Data classes also use this assembly. In your case, your Messaging
classes could use a similar assembly. This way, the Business classes could
be dependent upon the Messaging as well as the Data classes.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Complex things are made up of
Lots of simple things.
 
B

Bruce Barker

thats why you make a third project that's just the data defs. just create a
new library project and add to the solution. move the data classes (such as
vehicle to it). do not include any code that talks to data sources (or bi
logic).

now in the BI & Messaging classes create classes that inherit from the data
class, and add their logical methods. if you need a common method define a
default implementation in the data class and override in the others.

this is a good case of defining interfaces but inheritance will work fine.

-- bruce (sqlwork.com)




Joe said:
Hi Kevin,

Thank you so much for your reply. I can not break the reference to the
Business project that the Messaging project has. Please read on.

This company has two data sources. The Messaging project contains classes
that retrieve data from the third-party system (via XML). The Database
project contains classes that retrieve data from the company's home-grown
databases. They both have the same purpose: to retrieve data, but they
retrieve data from different sources in different ways.

The Messaging project references the Business project because its methods
use classes that are in the Business project (for eample, Vehicle,
CommercialUnit, Policy). The Business project classes have data retrieved
from the company's home-grown databases and now need to retrieve data from
the third-party databases. That's why the Business objects are passed to
the
Messaging classes; they contain information that the Messaging classes use
to
retrieve data.

I agree with you: a Business class should provide business logic for a
certain set of data. I, however, have no control over the initial design
of
this solution. The developers who built this solution designed it this
way
because they wanted the Messaging classes to be able to receive a business
object (say a Vehicle object with info about a certain vehicle); the
reason
that they did this is because a Vehicle has a ton of information connected
with it and they didn't want to have to pass 40 parameters to a Messaging
method call when they can jsut pass one object.

What I am trying to do is find a way to excapsulate data calls, so that
when
I ask for a piece of information regarding a Vehicle (for example), the
Business class will retrieve what I request from either the hown-grown
system
or the third-party system whichever is appropriate. The problem is that I
can not reference the Messaging project from the Business project because
that would create a circular reference.

What do you think? Still the same idea? Another?
 
G

Guest

Hi Bruce,

So in the third project (let's call it 'Third'), I have have an abstract
Vehicle class with no default implementations (let's assume that I don't need
them). Now, I create classes in each of the Business and Messaging projects
that inherit from the Vehicle abstract class in Third. Let's call these
BVehicle and MVehicle, respectively. Within each of these I implement
property and method calls. The calls in BVehicle will be different from the
calls in MVehicle (since each class retrieves different sets of data: i.e.
BVehicle calls the Database project's BVehicle class and receives VIN and
Make information becuase that's what's in the home-grown database; MVehicle
will retrieve Year and ValidateCoverages information because that's what's in
the third-party database.)

Now what? How does the UI project (i.e. my webform) use these? The idea
was to encapsulate all of the information in the Business project's Vehicle
class. Am I actually encapsulating it in the Third project's abstract
Vehicle class? I can't use the abstract class (because its abstract) so how
do I use these two classes to get the information that I want?

I want to be able to dim something as a vehicle and say:

Dim CarVIN as string = myCar.VIN '''''comes from home-grown database
Dim CarMake as string = myCar.Make '''''comes from third-party database

Thank you for your help,
 
K

Kevin Spencer

Hi Joe,

Well, I still think the design is flawed. Just as a database class doesn't
have to know anything about the data it is passing back and forth, only how
to connect and pass the data, the Messaging class is admittedly receiving
and sending XML. That is all the Messaging class should have to know. It's
for the Business class to serialize and deeserialize deserialize it. I mean,
what happens whenever you come up with a new object that the Messaging class
has to work with? Do you rebuild it? Your Messaging class sounds more like a
Business class to me.

However, it sounds like you have no say over whether this can be re-designed
correctly. Am I correct?

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Complex things are made up of
Lots of simple things.

Joe said:
Hi Kevin,

Thank you so much for your reply. I can not break the reference to the
Business project that the Messaging project has. Please read on.

This company has two data sources. The Messaging project contains classes
that retrieve data from the third-party system (via XML). The Database
project contains classes that retrieve data from the company's home-grown
databases. They both have the same purpose: to retrieve data, but they
retrieve data from different sources in different ways.

The Messaging project references the Business project because its methods
use classes that are in the Business project (for eample, Vehicle,
CommercialUnit, Policy). The Business project classes have data retrieved
from the company's home-grown databases and now need to retrieve data from
the third-party databases. That's why the Business objects are passed to
the
Messaging classes; they contain information that the Messaging classes use
to
retrieve data.

I agree with you: a Business class should provide business logic for a
certain set of data. I, however, have no control over the initial design
of
this solution. The developers who built this solution designed it this
way
because they wanted the Messaging classes to be able to receive a business
object (say a Vehicle object with info about a certain vehicle); the
reason
that they did this is because a Vehicle has a ton of information connected
with it and they didn't want to have to pass 40 parameters to a Messaging
method call when they can jsut pass one object.

What I am trying to do is find a way to excapsulate data calls, so that
when
I ask for a piece of information regarding a Vehicle (for example), the
Business class will retrieve what I request from either the hown-grown
system
or the third-party system whichever is appropriate. The problem is that I
can not reference the Messaging project from the Business project because
that would create a circular reference.

What do you think? Still the same idea? Another?
 
G

Guest

I have very, very little say in what happens. I do agree with you, though.
I just can't do much about it.

On that note, let's say that I could have my way. How would the Business
class serialize and deserialize itself? I've noticed that the other
projects' classes don't use objects from other projects. What I mean is that
most simply pass a String or Boolean value. Now this is where serialization
comes in, right? This is a good opportunity for me to learn something and I
really don't want to lose it. If I serialize the Business object (say,
Vehicle) how does the Messaging class know how to deserialize it so that it
can use it's properties?

Let's say that you could serialize and deserialize.... How would you do it?
What would you change? How would you decouple the Messaging project from the
Business project? Would this cost you any performance?

Thanks,
 
K

Kevin Spencer

Hi Joe,

Here's an example from a project I wrote, which has a class for logging,
called "DailyReport." The class is instantiated when a job runs in a
service, and is filled with logging data. This method serializes it to a
string. I have others that write the serialized contents to a file, or a
stream.

I should also mention that this class is a container for a collection of
other classes, each of which is a container for another collection of other
classes. They are all serialized in the same method, as members of this
class. You can ignore the program-specific code, and just look at the
serialization code. Here's one overload of the Serialize() method for the
DailyReport class.

/// <summary>
/// Serializes this instance to an XML Document string
/// </summary>
/// <returns>XML Document string</returns>
public string Serialize()
{
// ignore this. It is program-specific
DailyReport report = new DailyReport();
CopyTo(report, true);

// here's the part you're interested in
XmlSerializer serializer = new XmlSerializer(typeof(DailyReport));
MemoryStream ms = new MemoryStream();
serializer.Serialize(ms, report);
byte[] bytes = ms.ToArray();
Encoding enc = Encoding.Default;
return enc.GetString(bytes);
}

Here's one overload of the Deserialize method. It deserializes the
DailyReport from a file. Again, ignore the program-specific code, which
performs other business logic. The basic deserialization is actually quite
simple:

/// <summary>
/// Deserializes a DailyReport from a file
/// </summary>
/// <param name="filePath">Path to DailyReport File</param>
/// <returns>DailyReport</returns>
public static DailyReport Deserialize(string filePath)
{
DailyReport report = null;
if (!File.Exists(filePath))
return null;
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
// This is the part you should be interested in
XmlSerializer serializer = new
XmlSerializer(typeof(DailyReport));
report = (DailyReport)serializer.Deserialize(fs);

// The rest is program-specific stuff you should ignore
foreach (JobReport job in report.JobReports)
{
job.Parent = report;
foreach (FtpFile f in job.FtpFiles)
{
f.Parent = job;
f.FileContents = UtfFromAscii(f.FileContents);
}
}
}
}
catch (Exception ex)
{
Utilities.HandleError(ex, true, "filePath: " + filePath);
}
report.CalculateTotals();
return report;
}

I left it in context for clarity. As you can see, the basic nuts and bolts
of the serialization and de-serialization is quite simple.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Complex things are made up of
Lots of simple things.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top