c# - 在我的设计中实现自定义 Hook 的最佳方式

标签 c# events oop extensibility

我想知道将自定义 Hook 插入我的应用程序的最佳方法是什么。基本上,我的应用程序分为两个程序集:一个包含所有业务逻辑的 Core 程序集和一个包含 GUI、 Controller 类的 UserInterface 程序集(我使用的是异常的 MVC 模式调用“被动 View ”)和一些辅助类。核心程序集也被其他一些应用程序使用。

我的应用程序被我们公司用来处理来自其他公司的订单。所有公司的一般流程都是相同的,但这里和那里存在因客户而异的小偏差。截至目前,这些偏差已直接实现到闻起来有味道的核心组件中。我想将这些细节分开,最好将它们封装到每个客户的单个对象中,这样我就有了一个包含所有客户特定详细信息的中心对象,我可以将其放入 UserInterface 程序集中。

我考虑过使用事件来实现这一点。通过在我的核心类中添加一些事件,我的 Controller 类将能够为某些客户订阅或取消订阅实现这些偏差的方法。

我可以想到两种方法:手动添加这些绑定(bind),或者让它们自动添加(如果存在异常方法)。我正在为后者考虑这样的事情:

foreach (Order order in form.SelectedOrders) {
    CustomerExtension customer = customerExtensions[order.Customer];

    if(Exists(customer.StatusChanging(...)) // Pseudo Code!
            OrderManager.StatusChanging += new StatusChangingEventHandler(customer.StatusChanging(...));

    order.SetStatus(newStatus);

    if(Exists(customer.StatusChanging(...)) // Pseudo Code!
            OrderManager.StatusChanging -= new StatusChangingEventHandler(customer.StatusChanging(...));
}

我想我必须使用反射来实现这一点,但这对于需要多次执行的操作是否可行?

或者是否有更好的方法来添加自定义 Hook ,同时让我集中客户基础上的偏差?

[编辑] 完全修改了问题。

最佳答案

我认为你甚至可以在没有事件的情况下做到这一点(它们是你想要的结构吗?)。我试着整理一些东西:试着看一下代码(不要太在意细节),如果你想让我详细说明,请告诉我......:-)

// Begin personalization assembly (one of many)-----------------------

/// <summary>
/// Here you could use an attribute to allow clean reflection
/// </summary>
// [CustomerSpecific("Acme")]
public class AcmeCustomization : BaseCustomization
{
    public override void OnStatusChanged()
    {
        base.OnStatusChanged();
        // do what you need to customize
    }
}
// End personalization assembly (one of them)-------------------------

// Begin core assembly -----------------------------------------------
public interface ICustomization
{
    void OnStatusChanged();
}

/// <summary>
/// This class is optional of course, but can be useful
/// </summary>
public class BaseCustomization : ICustomization
{
    public virtual void OnStatusChanged()
    {
        // intentionally empty
    }
}

class CustomizationFactory
{
    public ICustomization GetCustomization(string order)
    {
        // Here you could
        // - hardcode (as you did in your solution)
        // - use reflection (various ways)
        // - use an external mapping file
        // - use MEF (!)
        // and then
        // - do instance caching
        // - whatever...

        // I'm lazy ;-)
        return null;
    }
}

class OrderManager
{
    private ICustomization _customization = null;

    public void SetStatus(string order, int status)
    {
        // Do some work
        this.OnStatusChanged();
        // Do some other work
    }

    protected void OnStatusChanged()
    {
        if (_customization != null)
        {
            _customization.OnStatusChanged();
        }
    }

    public void SetCustomization(ICustomization customization)
    {
        _customization = customization;
    }

    public void ClearCustomization()
    {
        _customization = null;
    }
}
// End core assembly -------------------------------------------------

class Program
{
    static void Main(string[] args)
    {
        CustomizationFactory factory = new CustomizationFactory();
        OrderManager manager = new OrderManager();

        // here I'm just pretending to have "orders"
        var orders = new string[] { 
            "abc",
            "def"
        };

        const int newStatus = 42;

        foreach (var order in orders)
        {
            manager.SetCustomization(factory.GetCustomization(order));
            manager.SetStatus(order, newStatus);
            manager.ClearCustomization();
        }
    }
}

HTH

关于c# - 在我的设计中实现自定义 Hook 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1366115/

相关文章:

events - C++ 中的自定义事件/中断处理

c# - 如何更改dataGridView中的提交值?

php - 关键字错误,从网站中提取内容。面向对象

javascript - 将属于对象的匿名方法作为参数传递 - Javascript

Javascript OOP - jQuery 在 ajax 请求中调用 "this"

c# - Windows 窗体应用程序上与 NotifyIcon 关联的 ContextMenu 的 MenuItem 上的单击事件未触发,但需要再单击一次图标才能工作

c# - 将 C# 代码从 Cassandra .5 迁移到 .6

c# - 使用 lambda 重新排列 List<T>

c# - 使用正则表达式匹配但不包含在结果中

java - MouseAdapter 中 isPopupTrigger() 的正确处理是什么