设计模式允许在某些点注入代码

发布于 2024-08-02 17:09:00 字数 786 浏览 5 评论 0原文

我试图允许开发人员在某些执行点扩展我的代码。

我的具体示例是数据库事务包装器。包装器负责我们希望从开发人员那里抽象出来的许多细节,并在多个项目中使用。

然而,每个项目都有一些他们希望在交易期间自动执行的操作。我想添加每个项目都可以设置来运行代码的拦截点。

例如,我们数据库中的每个表都有一个“输入日期”字段,每次记录更改时该字段都会更新。然而,我们希望无论涉及多少条记录,交易的所有日期都相同(即表 A 中有 4 条记录,表 B 中有 1 条记录,...)。

我的想法是定义拦截点“TransactionStarting”、“TransactionStarted”、“StatementExecuting”、“StatementExecuted”……并将上下文对象传递给每个点。

然后,项目可以定义一个类“EnteredDateManager”,用于存储“TransactionStarted”点期间的当前日期,并在“StatementExecuting”点期间更新每个对象的 EnteredDate 属性。

我想在 web/app.config 文件中进行设置并允许注册多个拦截类。如果注册了多个班级,则应按注册顺序解雇他们。

我本来只想引发事件,但我希望秩序很重要。我还希望能够在不同点之间共享状态。在上面的示例中,EnteredDate 属性在 TransactionStarted 点中设置并在 StatementExecuting 点中使用。

这是责任链模式吗?奥普?它似乎与 ASP.Net 管道的工作方式很接近,但据我所知,它们使用事件并且不保证顺序。

任何方向/例子都会很棒。

谢谢

I am trying to allow developers to extend my code at certain points of execution.

My specific example is a database transaction wrapper. The wrapper takes care of many details that we wanted to abstract away from the developer and is used on several projects.

Each project however has certain things they would like to do automatically during the transaction. I would like to add interception points that each project can setup to run code.

For example, each table in our database has an Entered Date field that is updated every time the record changes. We however want all the dates to be the same for a transaction across however many records are touched (i.e. 4 records table A, 1 record in table B, ...).

My thought is to define interception points "TransactionStarting", "TransactionStarted", "StatementExecuting", "StatementExecuted", ... and pass a context object to each point.

Then the project can define a class "EnteredDateManager" that stores the current date during the "TransactionStarted" point, and updates each object's EnteredDate property during the "StatementExecuting" point.

I would like to set this up in the web/app.config file and allow multiple interception classes to be registered. If more than one class is registered, they should be fired in the order they were registered.

I was thinking of just raising events, but I want order to matter. I also want to be able to share state between the different points. In my example above, the EnteredDate Property is set in the TransactionStarted point and used in the StatementExecuting point.

Is this the Chain of Responsibility pattern? AOP? It seems close to how the ASP.Net pipeline works, but they use events and don't guarantee ordering as far as I know.

Any direction/examples would be great.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷迭香的记忆 2024-08-09 17:09:00

对我来说听起来像是面向方面的编程。查看 PostSharp

这是从他们的网站进行跟踪的示例:

public class TraceAttribute : OnMethodBoundaryAspect 
{ 
  public override void OnEntry( MethodExecutionEventArgs eventArgs) 
  { Trace.TraceInformation("Entering {0}.", eventArgs.Method);  } 

  public override void OnExit( MethodExecutionEventArgs eventArgs) 
  { Trace.TraceInformation("Leaving {0}.", eventArgs.Method);   } 
}

我用它来进行日志记录/跟踪、缓存和性能监控。

Sounds like Aspect-Oriented Programming to me. Check out PostSharp.

Here's an example of tracing from their website:

public class TraceAttribute : OnMethodBoundaryAspect 
{ 
  public override void OnEntry( MethodExecutionEventArgs eventArgs) 
  { Trace.TraceInformation("Entering {0}.", eventArgs.Method);  } 

  public override void OnExit( MethodExecutionEventArgs eventArgs) 
  { Trace.TraceInformation("Leaving {0}.", eventArgs.Method);   } 
}

I use it to do logging/tracing, caching and performance monitoring.

一直在等你来 2024-08-09 17:09:00

实现此目的的一种方法是仅使用基本策略模式。使用策略,您基本上将功能推入一个单独的类中,该类将由您的类调用,而不是直接在原始类中实现逻辑。可以通过基于接口的属性或通过构造函数参数(或两者)设置策略类,将其包含在原始类中。这样,用户可以选择将不同类型的功能注入到原始类定义的某些处理流程中。

One way to do this is to just use the basic Strategy pattern. With Strategy, you're basically pushing functionality into a separate class which will be called by your class, rather than implementing the logic directly in the original class. The strategy classes can be included in the original class by setting them via interface-based properties, or through constructor arguments (or both). This way, the user can choose to inject different types of functionality into some processing flow defined by the original class.

昇り龍 2024-08-09 17:09:00

如果这是 .NET 特定的(您提到了 ASP.NET),我强烈建议您查看 System.Transactions 命名空间,并阅读有关在事务中创建和注册资源管理器的信息。

使用 TransactionScope,您可以在上下文中创建事务,并且在该上下文中执行的资源管理器可以检测事务的存在并注册到其中(这将与 TransactionStart 事件同义)。注册后,每个资源管理器都可以选择提交其更改,或者退出并启动事务回滚。

Systen.Transactions 命名空间是随 .NET 2.0 引入的,它提供了一些非常强大的工具来创建事务和管理事务资源。您可以选择轻量级事务,或者如果您需要更复杂的、由 MSDTC 服务管理的完全分布式事务。事务可以是单阶段提交,也可以是两阶段提交,在面对事务失败时提供了很大的灵活性和稳定性。

If this is .NET specific (you mentioned ASP.NET), I would highly recommend looking into the System.Transactions namespace, and read about creating and enrolling resource managers in a Transaction.

Using TransactionScope, you can create a transaction in context, and resource manager executing within that context can detect the presence of a transaction and enroll in it (this would be synonymous with your TransactionStart event). Once enrolled, each resource manager then has the option to either commit its changes, or back out and initiate a rollback of the transaction.

The Systen.Transactions namespace, which was introduced with .NET 2.0, offers some pretty powerful tools to create transactions and manage transacted resources. You have the option of both lightweight transactions, or if your needs are more complex, fully distributed transactions managed by the MSDTC service. Transactions can be single-phase commit, or two-phase commit, offering a lot of flexibility and stability in the face of transaction failure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文