CSLA 6 how to create a child in a BusinessBindingListBase? #2848
-
What is the CSLA 6 equivalent to: protected override object AddNewCore()
{
var item = Child.NewChild();
Add(item);
return item;
} I was expecting Are we meant to IDataPortal<Child.Factory> ChildFactory { get; set; }
protected override object AddNewCore()
{
var item = Child.NewChild(ChildFactory);
Add(item);
return item;
}
[CreateChild]
private void Create([Inject] IDataPortal<Child.Factory> childFactory)
{
ChildFactory = childFactory;
}
[FetchChild]
private void Fetch(Guid parentId,
[Inject] IChildDal dal,
[Inject] IChildDataPortal<Child> childDataPortal,
[Inject] IDataPortal <Child.Factory> childFactory)
{
using (LoadListMode)
{
var list = dal.FetchList(parentId);
foreach (var dto in list)
{
var item = Child.GetChild(childDataPortal, dto);
Add(item);
}
}
ChildFactory = childFactory;
} |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 16 replies
-
The The child data portal is not location neutral and must be running on the logical server within the context of the server-side data portal. None of this is new, but in CSLA 6 it is more clear that you really shouldn't be using the child data portal independently on the client. The solution is to create a child getter/creator/factory/whatever class to create/get the child. Somewhat like: [Serializable]
public class ChildFactory : ReadOnlyBase<ChildFactory>
{
public static readonly PropertyInfo<ChildType> ChildProperty = RegisterProperty<string>(nameof(Child));
public string Child
{
get { return GetProperty(ChildProperty); }
private set { LoadProperty(ChildProperty, value); }
}
[Create]
private async Task Create([Inject]IChildDataPortal<ChildType> childPortal)
{
Child = await childPortal.CreateAsync();
}
[Fetch]
private async Task Fetch(int id, [Inject]IChildDataPortal<ChildType> childPortal)
{
Child = await childPortal.FetchAsync(id);
}
} Then in your Of course you can use the |
Beta Was this translation helpful? Give feedback.
-
As I was waking up this lazy Saturday morning I had a thought. So take it for what it is worth, but I think I'm right. Why can't you just put a fetch operation on the child class? It gets set to be a child as it is added to the collection, not during the data portal operation. Then you can use the normal root |
Beta Was this translation helpful? Give feedback.
-
I'm revisiting this almost 30 months later as I'm restructuring a lot of our base classes. Being able to create a child with a regular With an public interface IMarkAsChild
{
void MarkAsChild();
}
public static class IDataPortalExtensions
{
public static T CreateChild<T>(this IDataPortal<T> portal, params object[] criteria)
{
var child = portal.Create(criteria);
if (child is IMarkAsChild markAsChild)
markAsChild.MarkAsChild();
return child;
}
}
// Our wrapper for BusinessBase:
[Serializable]
public abstract class BusinessBaseMgd<T>
: BusinessBase<T>
, IMarkAsChild
where T : BusinessBaseMgd<T>
{
void IMarkAsChild.MarkAsChild() => MarkAsChild();
} Alternatively, has anyone come up with a better solution in the last couple of years? |
Beta Was this translation helpful? Give feedback.
-
@rockfordlhotka Can you provide some further context to your comment
|
Beta Was this translation helpful? Give feedback.
-
imo the best solution, if you need to create a new child on the logical server, is to use a command object. Typically created using public class ChildCreator : ReadOnlyBase<ChildCreator>
{
// csla property
public Child Child { get; set; }
[Fetch]
private async Task FetchAsync([Inject] IChildDataPortal<Child> childPortal)
{
Child = await childPortal.CreateAsync();
}
} On the logical client, when you need to create a new child, use the root data portal: var newChild = await childCreatorPortal.FetchAsync(); |
Beta Was this translation helpful? Give feedback.
As I was waking up this lazy Saturday morning I had a thought. So take it for what it is worth, but I think I'm right.
Why can't you just put a fetch operation on the child class? It gets set to be a child as it is added to the collection, not during the data portal operation. Then you can use the normal root
FetchAsync
method on the client-side data portal to retrieve the object, which is then added to the parent and becomes a child.