Future data portal redesign #3554
Replies: 2 comments 5 replies
-
I will be happy to help with this effort in any way I can as things progress. To start, let me share a different pattern I implemented in my LOB app and business objects which removes the need for the front-end UI/app developer to know anything about the DataPortal. They only need to inject Here is the code in a Blazor Component calling an editable business object: @inject NotificationService _notifSvc;
@inject Csla.ApplicationContext _appContext;
...
try
{
var labToEdit = BL.LabEdit.GetLab(_appContext, labId);
...
}
catch (Exception ex)
{
_notificationService.AddErrorNotification(ex);
} Here is the factory code in that business object: public static LabEdit NewLab(ApplicationContext appContext)
{
var newObj = GetDataPortal(appContext).Create();
newObj.BusinessRules.CheckRules();
return newObj;
}
public static LabEdit GetLab(ApplicationContext appContext, string id)
{
var newObj = GetDataPortal(appContext).Fetch(id);
newObj.BusinessRules.CheckRules();
return newObj;
}
... Here is the [Serializable()]
public abstract class MyRootBusinessBase<T> : MyCommonBusinessBase<T>
where T : MyRootBusinessBase<T>
{
protected static IDataPortal<T> GetDataPortal(ApplicationContext appContext)
{
var portalFactory = appContext.GetRequiredService<IDataPortalFactory>();
var portal = portalFactory.GetPortal<T>();
return portal;
}
...
} I don't want to lose that simplicity....(too early but at this point) but I expect I'd be looking for ways to use abstraction to put your numbers 2 and 3 back together again so that every CRUD call does not require 4 separate checks (success with object 1, success no object 2, failure 3, dp failure 4). This abstraction layer could take care of any further "sanitizing" in line with the concerns so clearly expressed by @TheCakeMonster while putting separate things back into one simple Exception scenario (what you wanted to happen didn't happen). |
Beta Was this translation helpful? Give feedback.
-
IMO #2 and #3 aren't different though; I think that exceptions are warranted when the method cannot fulfil its contract. Take for example a method GetOrderById. Whether that's due to a network issue, or a user asking for object id 1353 which doesn't exist, the method didn't do what was expected of it. The only difference would be the error message we'd show the user. Separating them means you need to check for result codes and handle exceptions. Just wanted to say that, but if this does move forward I'm glad to hear it would be opt-in :-) |
Beta Was this translation helpful? Give feedback.
-
Between @TheCakeMonster and @swegele, I've started thinking that maybe a future data portal API and implementation is something to consider (maybe for CSLA 9).
Take @TheCakeMonster 's comment on a thread and @swegele 's comments in this thread as a start.
As I mentioned to @swegele, if I'd thought about the data portal as a service API the way I think about those things today - but back in 1997 or 2001 - I think we'd have something a lot more like what @TheCakeMonster is talking about. The data portal would provide exactly three possible results:
The current data portal pretty much lumps numbers 2 and 3 together, which is very awkward.
Sure, there could be numerous workarounds to solve this using the current data portal. The easiest being an abstraction using what amounts to a Unit of Work (UOW) pattern where you use the data portal to always interact with one
DataPortalOperation<T>
type.Basically, do to the data portal what the data portal does to http/gprc/wcf/etc. Abstract it away.
And that might be what this future implementation will do too, because one of my primary requirements in this potential rethink is to leave the existing data portal functionality alone. I don't want to break literally every CSLA app out there! Any data portal redesign needs to be opt in, so people can ignore it, migrate to it over time, or adopt it how they choose.
Calling Code
I'd like this new data portal to always return a consistent type, maybe like this:
Or an exception - basically today's
DataPortalException
, but only in the case of a true exception.This means someone calling the data portal would do something like this (to show the concept):
On the Server
I'm not sure the server-side code can change a lot. It does need to change so it can create and return the "failure" type for the call.
The thing that can't really change is the use of exceptions to indicate failure, because we rely on that to roll back transactions in ADO.NET, Dapper, EF, etc. Pretty much all the data access frameworks out there rely on exceptions to trigger a rollback.
I must confess that I haven't thought through the detail on this yet - exactly what a data portal operation will look like. But perhaps something with a "context" parameter?
Realistically, that
context.Success(this)
call shouldn't be necessary, as that'd be the default behavior, barring an exception. Ifcontext.Failure()
is called, that'd override the default behavior, and only return the failure object.Beta Was this translation helpful? Give feedback.
All reactions