如何在每个方法调用后隐式调用一个方法?

Shw*_*hak 17 c#

对不起,该帖子的标题很棒.我有点好奇知道以下问题是否有任何解决方案.情况是我有一个函数调用SaveSecurity();,我需要在每个函数后调用它.如下所示:

public void AddUser(string ID, string Name, string Password)
{
    ///some codes
    SaveSecurity();
}
public void DeleteUser(User ObjUser)
{
    ///some codes
    SaveSecurity();
}
public void AddPermission(string ID, string Name, AccessType Access)
{
    ///some codes
    SaveSecurity();
}
public void DeletePermission(Permission ObjPermission)
{
    ///some codes
    SaveSecurity();
}
public void AddRole(string ID, string Name)
{
    Roles.AddRole(ID, Name);
    SaveSecurity();
}
public void SaveSecurity()
{
    ///Saves the data
}
Run Code Online (Sandbox Code Playgroud)

还有很多.所以现在如果我们看一下所有函数的相似性,最后它会SaveSecurity()在函数结束后调用它.我的问题是:

有没有办法在每个函数之后调用此函数,而不是一次又一次地写同一行?

我的类图看起来像这样

在此输入图像描述

Mat*_*ics 8

您需要查看存储库模式,

分开你的课程和那里的行动,

创建另一个层(称为业务层)或任何将调用不同类的不同方法的层...

ATM你试图跟随OOP,但你所做的只是函数式编程..

在ASP.NET MVC应用程序中实现存储库和工作单元模式

编辑添加类图后

您的集合类实际上是存储库类,您需要将deletePermissions,deleteRole等方法移动到各自的存储库类,例如permissionsRepo(如果需要,将其命名为集合)和roleRepo.

所以你已经拥有了一个对象类和一个对象的存储库类(可以在一起),但我喜欢将它们分开,repostory类将做他们需要做的事情,比如..

// Make changes to DB
// Make changes to AD
// Makes changes to web services etc...
Run Code Online (Sandbox Code Playgroud)

您的经理类可能会设置存储库类的方法,但它们只会调用它们,

PermissionManager.DeletePermissions(PermissionObject);
Run Code Online (Sandbox Code Playgroud)

然后在PermissionManager类中你将有方法,

DeletePermissions(Permissions pObject)
{
     PermissionRepo.Delete(pObject);
}
Run Code Online (Sandbox Code Playgroud)

以上只是添加一个图层,使您的代码在非常短的时间内看起来更具可读性和未来性,但如果您有更多时间进行投资,您也可以查看Observer模式...

在C#中实现Observer模式

每次你的对象改变它的状态你就可以调用SaveSecurity方法(它将在另一个类中(Name it changes可能).如果你不想调用SaveSecurity对象的每次更改,你可以为你的对象添加一个属性,例如IsSecurityChanged?如果是,则调用SaveSecurity.

更多解释,但如果你看看上面的观察者模式,你会得到一个想法.

还有一种方法,但我个人不会建议使用IDisposable接口,然后在dispose方法中为对象调用SaveSecurity方法.但我不推荐它.


Pat*_*man 6

只有C#你不能,但有一些解决方案可能有所帮助.

我所知道的最好的是PostSharp.它将使您能够在调用方法之前和之后定义操作(例如).有关它的一些信息可以在这里这里找到.

那么你唯一要做的就是SaveSecurity用属性来装饰你想要调用的方法.

如果您不想使用此类工具,请保持原样.这是好的方式.

  • 如何在每个方法之前要求一个属性装饰器比在最后要求函数调用更好?你很可能会忘记另一个,它并没有解决重复代码的问题,只是将它从方法的底部移到顶部.充其量,这可能会增加它的可见性,使您更容易看到是否错过了一个,但实际上它只是添加了另一个移动部分,这会产生更多的错误空间. (2认同)

Alp*_*dar 5

您可以使用某种面向方面的编程(不知道如何在C#中进行,而是尝试对其进行谷歌搜索)。

除了简单地在另一个函数的末尾调用一个函数外,另一种方法不是更好,它是创建具有函数参数的帮助程序函数,该函数执行该函数的参数,然后调用您的安全函数。但是每个函数的主体看起来像(如果我正确记得C#lambda):

CallAndSaveSecurity(() => /* some code */);
Run Code Online (Sandbox Code Playgroud)

因此,它将包含比原始解决方案更多的东西。

顺便说一句,也许您仍然需要更多电话。如果您希望即使在异常发生时也要调用该函数,则需要

try{
  // some code
} finally {
  SaveSecurity();
}
Run Code Online (Sandbox Code Playgroud)

并将其隐藏在功能助手中是有道理的。

  • 想法很好。但这不能解决我的问题。Bcoz还是我的代码看起来一样。还有其他想法吗? (2认同)