我想知道将自定义 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/