How to use injected DataPortal in business rules and workarounds for static methods? #2681
Replies: 3 comments 9 replies
-
In the latest preview that Rocky released yesterday, the BusinessBase, CommandBase, and ReadOnlyBase classes have a GetDataPortal method. I think this may solve some of, if not all of your issues. BusinessRuleBase does not have one, but perhaps it can be passed in as a parameter. Havn't had a chance to try for myself yet. Link to commit: |
Beta Was this translation helpful? Give feedback.
-
Regarding the use of static factory methods, I really need to write a blog post about this soon, because it is the biggest hurdle most people are encountering. You can not use static factory methods - there's no safe way to make that happen. There are alternatives. First, you can drop the use of factory methods and just use Second, you can create a factory class and put your static factory methods into that class as instance methods. This factory class will require the necessary Third, and this only works in WinForms or WPF, you can implement a static |
Beta Was this translation helpful? Give feedback.
-
I think you could still use static factory methods if you wanted to - but only if you pass the data portal in as a parameter. Here's an example of what you can do: public static MyBusinessType NewMyBusinessType(IDataPortal<MyBusinessType> dataPortal, int id)
{
return dataPortal.Create(new IDCriteria(id));
} I have chosen to do this in order to get a lot of the tests migrated; it turned out to be quicker than the alternatives on many dozens of classes there are in the test project. This may be a step towards something else as other contributors/reviewers may frown on it, but it was a pragmatic choice to get us working tests. One step at a time! As it happens, although it's a little odd as a pattern, I think there are some benefits to doing this:
It's possible to get some of these benefits using other means, but so far I haven't found another way of getting as many. Creating a separate factory class for each BO type that can be registered with DI and injected into your components should work too, but you'd have to either change the criteria classes to have a wider scope, or maybe nest the factory type inside of the BO type, which results in slightly more awkward syntax for the user of the factory type. |
Beta Was this translation helpful? Give feedback.
-
Can someone give an example of how to utilize the DataPortal in a business rule for CSLA 6? Now that the DataPortal is being injected and not static, I'm not sure how to use it. So for example I have this rule:
How can that be rewritten in CSLA 6?
Additionally, I have concerns with no longer being able to utilize static methods in my BOs. I've been supporting a project utilizing CSLA since v3, and have been updating that project with each new iteration, but past iterations still allowed for me to utilize some older methodologies, when I couldn't quite make things fit with the newer ones. For example, a lot of my per type authorization rules needed more than just a user's role and required checking a database for additional security that may have been put on a record. To make this work, I kept utilizing the old CanGetObject static functions from v3 and passed in the necessary parameters. I would then call the static authorization methods from within the static factory methods. Here's an example:
While it is extra work, it is flexible enough so that I have the authorization I need on my objects. However, with the new injected DataPortal, I'm not sure how to make this work anymore, since I can no longer use the static methods. This was why I was inquiring about async authorization rules last month (#2643), because the current out of the box solution for CSLA 6 won't work in blazor which requires async dataportal methods. Is there some workaround that I can do until async auth rules are an option?
Finally, I feel like while moving to an injected DataPortal seems to be necessary, the tradeoff is losing a lot of the nice encapsulation that CSLA's BOs provided. It was nice being able create static methods so that when instantiating a business object, you knew what parameters were needed with the static factory method. Now it looks like those parameters are just a param array being called from the UI's injected DataPortal, which loses the ability to pick up bugs at compile time.
Additionally, things like additional methods that are pertinent to the BO, but outside the scope of Create/Fetch/Insert/Update/Delete can now no longer be easily encapsulated. For example on the ProjectEdit BO in your Project Tracker Project:
I assume that now, that check will have to be made directly from the UI and inject the DataPortal with the ProjectExistsCommand. So instead of the user just needing to work with ProjectEdit, they have to work with the command BO directly.
This could also just be my lack of understanding with the new methodologies, and there is a way to use injection while still maintaining this encapsulation. Please let me know if there is a way to do any of the 3 things I've mentioned.
I also want to state that I'm not complaining here. I just want to know how to make this stuff work. I think CSLA is amazing, and have been using it for the past 17 years. I appreciate all the thought and work that goes into it. Hopefully, I will have a better understanding of how to make these things work once more examples are available.
Beta Was this translation helpful? Give feedback.
All reactions