Add GetDataPortal<T>() function publicly to ApplicationContext #2733
-
Is it possible to add a GetDataPortal() function directly to the injected ApplicationContext? This would make things a little easier when converting my static methods. So using my earlier example from #2681 public static async Task<bool> CanGetObjectAsync(int clientID, IDataPortal<HasPermissionForClientCommand> cmdPortal)
{
var result = default(bool);
if (BusinessRules.HasPermission(AuthorizationActions.GetObject, typeof(Client)))
{
HasPermissionForClientCommand cmd = await cmdPortal.CreateAsync(clientID, AccessPermissions.ReadAccess);
cmd = await cmdPortal.ExecuteAsync(cmd);
result = cmd.HasPermission;
}
return result;
}
public async static Task<Client> GetClientAsync(int clientID, IDataPortal<Client> clientPortal, IDataPortal<HasPermissionForClientCommand> cmdPortal)
{
var canGet = await CanGetObjectAsync(clientID, cmdPortal);
if (!canGet)
{
throw new System.Security.SecurityException("User not authorized to load this Client");
}
return await clientPortal.FetchAsync<Client>(clientID);
} You can see that I have to pass in multiple DataPortals into my method, one for the command object to check for authorization, and the other for retrieving the object. I would rather just pass in the ApplicationContext, and then have that issue the dataportals within the method. That way the Consumer wouldn't even need to know what dataportals are needed. So something like this: public static async Task<bool> CanGetObjectAsync(int clientID, ApplicationContext appContext)
{
var result = default(bool);
if (BusinessRules.HasPermission(AuthorizationActions.GetObject, typeof(Client)))
{
var cmdPortal = appContext.GetDataPortal<HasPermissionForClientCommand>();
HasPermissionForClientCommand cmd = await cmdPortal.CreateAsync(clientID, AccessPermissions.ReadAccess);
cmd = await cmdPortal.ExecuteAsync(cmd);
result = cmd.HasPermission;
}
return result;
}
public async static Task<Client> GetClientAsync(int clientID, ApplicationContext appContext)
{
var canGet = await CanGetObjectAsync(clientID, appContext);
if (!canGet)
{
throw new System.Security.SecurityException("User not authorized to load this Client");
}
var clientPortal = appContext.GetDataPortal<Client>();
return await clientPortal.FetchAsync<Client>(clientID);
} This would just make life a lot easier not needing to know what DataPortal types need to be injected from the UI, as well as still being able to make use of static methods, just passing in the ApplicationContext. If this is a bad idea, just let me know, but I think it would give better flexibility with migrating from v5.x. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
I think I'd rather add something like a DataPortalFactory concept. ApplicationContext already violates the single responsibility pattern, and I hesitate to keep adding functionality that makes it worse in that regard. However, the need to inject numerous data portal instances is not unique to your scenario. It is also (I'm finding) quite common in data portal operation methods where a root class is responsible for loading a lot of child types, or in a command object that interacts with numerous business types. Being able to inject an IDataPortalFactory that is then used to get the various data portal instances might be a good solution. Issue #2676 is tracking this idea - I added some more thoughts to it today. |
Beta Was this translation helpful? Give feedback.
I think I'd rather add something like a DataPortalFactory concept.
ApplicationContext already violates the single responsibility pattern, and I hesitate to keep adding functionality that makes it worse in that regard.
However, the need to inject numerous data portal instances is not unique to your scenario. It is also (I'm finding) quite common in data portal operation methods where a root class is responsible for loading a lot of child types, or in a command object that interacts with numerous business types.
Being able to inject an IDataPortalFactory that is then used to get the various data portal instances might be a good solution.
Issue #2676 is tracking this idea - I added some more…