Hi,
Essentially, the book (VB 2005 Business Objects SE) uses a single project that contains everything: the properties (or Business Methods), Factory Methods, and Data Access. While this is great for using one database platform, we have used multiple projects to allow us to use multiple database engines. So instead of having to reproduce all of the properties and their business rules in each data project, we just inherit it in each. Although the book mentions this in a couple of lines, there are no examples. Does anyone have an example?
The reason I'm asking is because we are upgrading from 1.1 to the latest CSLA framework and the problem is that certain things conflict with the two project methodology.
For example (and this is just one example):
Public Shared Function NewWhatever() As Whatever
Return DataPortal.Create(Of Whatever)()
End Function
This does not work, because Whatever is marked as a MustInherit class and you cannot create an instance of such a class. It worked in our old methodology because the previous person who did the work tweaked the methods (i.e. never used Shared, had another factory project, etc) to get everything to work. I, on the other hand, want to take the time now to make sure that everything makes reasonable sense before we go into massively chaning large portions of code to work with the new CSLA.
Any examples that I can look at? Anyone have any ideas?
Greatly appreciated..
A
Disclaimer: I did not have to write a project yet against
multiple databases. However, if I had to do it, I would have tried to
have a single set of business objects, and have DB specific code in data portal
methods. Moreover, I would have tried to have database factory (of sorts)
that would look in config and create appropriate objects for database currently
used. Something like: Factory.CreateConnection as DBConnection (or
IDBCOnnection), etc… for other db objects. That way your business
object code is database agnostic altogether. Just a thought…
Sergey Barskiy
Senior Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: andrewem
[mailto:cslanet@lhotka.net]
Sent: Wednesday, May 07, 2008 1:12 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Using Csla with Inheritance and Multiple Database
Engines
Hi,
Essentially, the book (VB 2005 Business Objects SE) uses a single
project that contains everything: the properties (or Business Methods), Factory
Methods, and Data Access. While this is great for using one database platform,
we have used multiple projects to allow us to use multiple database engines. So
instead of having to reproduce all of the properties and their business rules
in each data project, we just inherit it in each. Although the book mentions
this in a couple of lines, there are no examples. Does anyone have an example?
The reason I'm asking is because we are upgrading from 1.1 to the latest
CSLA framework and the problem is that certain things conflict with the two
project methodology.
For example (and this is just one example):
Public Shared Function NewWhatever() As Whatever
Return DataPortal.Create(Of Whatever)()
End Function
This does not work, because Whatever is marked as a MustInherit class and
you cannot create an instance of such a class. It worked in our old methodology
because the previous person who did the work tweaked the methods (i.e. never
used Shared, had another factory project, etc) to get everything to work. I, on
the other hand, want to take the time now to make sure that everything makes
reasonable sense before we go into massively chaning large portions of code to
work with the new CSLA.
Any examples that I can look at? Anyone have any ideas?
Greatly appreciated..
A
Does anyone else have an ideas?
One project contains the business properties etc. The other project contains the data access methods. And there is a factory layer currently that creates the objects. We have the existing methodology working perfectly. BUT, we want to develop something that closely follows the book.
My question in essence is if anyone has a rough template that shows Rocky's code and then it split up into the two projects. I can't imagine I'm the only one who uses the CSLA with multiple databases and I hope no one is going to advocate reproducing everything over and over again for each different database.
A
Sergey description is spot on.
I supported Oracle and SQL Server with the same CSLA BOs. I simply created a config file setting like DBType and set it to "Oracle" or SQL Server".
I have a separate Data Access Layer (DAL) which contain all the ADO.Net code and it reads the config file and creates instances of either the OracleReader or the SqlReader. (and Connection and ...). But the DAL always returns the interface IReader instead of the concrete type. Then all my BO code uses the IReader or whatever and it does not know the difference bewteen the 2 databases.
HTH
Joe
Hi,
I want to keep everyone up to date on my plight. I appreciate the help, but in the case above, what if I want to use a data source that doesn't conform to the Interfaces provided by .NET (for example, what if I want to use LINQ or web services to populate my class properties?)
So, I have everything set up the way I want it. I have my two assemblies (projects) with inheritance - similar to the working model we have, BUT, there is a snag: this version of the CSLA uses generics, which I like, but consider this:
DataPortal.Fetch(Of <business object>)
The <business object> in this case is mustinherit (abstract), so the the CSLA tries to create the abstract object and of course that fails.
The old CLSA version never used inheritance, so we could create the business object using a factory and call DataPortal.Fetch and it would never create it each time (or at least in the implementation we were using that I have happened to inherit).
A
andrewem:Hi,
I want to keep everyone up to date on my plight. I appreciate the help, but in the case above, what if I want to use a data source that doesn't conform to the Interfaces provided by .NET (for example, what if I want to use LINQ or web services to populate my class properties?)
Then you code your DAL project to manage whatever your data sources are. If you are supporting disparate data sources - especially if one of them is a web service - then your best bet is to probably use DTO's to transfer your data. I responded to another thread outlining some of this (http://forums.lhotka.net/forums/thread/12631.aspx), but basically you put your DTO's into a separate assembly, and use those to transmit your data back and forth between your DAL and your BO's.
So, I have everything set up the way I want it. I have my two assemblies (projects) with inheritance - similar to the working model we have, BUT, there is a snag: this version of the CSLA uses generics, which I like, but consider this: DataPortal.Fetch(Of <business object>) The <business object> in this case is mustinherit (abstract), so the the CSLA tries to create the abstract object and of course that fails. The old CLSA version never used inheritance, so we could create the business object using a factory and call DataPortal.Fetch and it would never create it each time (or at least in the implementation we were using that I have happened to inherit).
You've asked this question several times in several different places, so you must not be getting the answers that you want (or any at all). I'm not sure what you mean by "the old CSLA never used inheritance", but that's not really what's got me scratching my head. I'm going to step back a bit and ask a different question:
Why would you want to call a DataPortal method with an abstract class?
I must not be getting it, because for the life of me I can't see how that buys you anything. You have to cast that everywhere. I know that you're trying not to have to re-write a bunch of existing code, but I just don't see how that design was helpful, regardless of the version of CSLA used. IMHO, sometimes it's just better to rip off the band-aid...
- Scott
Hi Scott,
Don't worry about it. I've found a solution. I have compiled a list of all the solutions that people stated on here, but many of them have problems. For example, using Interfaces such as IDBConnection doesn't work very well if you are using Web Services (for example) to obtain your data. These DTO's we were looking at seem to add a whole new level of complexity to something that for the way we were doing it originally was simple and worked.
I realize that there are many 'solutions' that everyone has out there to this problem, we've found one that works for us and has suited us well over the past four years.
A
Create an interface for the datacalls you want. Create an implentation of each of these for DB, WS etc (Strategy Pattern). You are basically creating a strategy pattern for your DAL calls. You can extend this to MSMQ qnd even add a composite pattern to use two at the same time or automatic rollovers should one become unavailable. Oh and create youself a factory for loading teh concrete types.
public interface DALFacade
{
public Order GetOrders();
}
public class WebServiceDALFacade
{
public Order GetOrders(){...call webservice DAL.}
}
public class DataBaseDALFacade
{
public Order GetOrders(){
..Here you can load the dataprovider by a factory class.
DataProvider provider = DataProvider.CreateProvider( some variable to determine sql, oracle etc.
provider.createparamter(.......);
provider.createClobParameter(.........);
IDataReader reader = provider.ExecuteReader(...................);
Build Order from reader (create as a seperate method and loop through fields setting values using the field name. This way you can reuse the build for every db command that builds an order object. rather than creating crazy new(...............................................................) with 100 params everytime you create the object. My view is the order of a stored procedure is much more likely to change than the field names.
}
}
Copyright (c) Marimer LLC