您可以在其他Customization包上调用方法吗?

问题描述

我们有一项计划,需要在两个不同的自定义程序包之间进行通信。因此,我们有了定制A,它需要调用最适合在定制B中实现的方法。到目前为止,我的想法是设置一个WebHook,然后通过直接从定制A中调用Webhook来调用我们需要的功能。实施此程序后,我想伸出手去看看其他人如何解决了这一要求。是否可以直接在C#中从其他自定义调用函数,但我没有遇到任何引用,因此我认为这是不可能的?但是想伸出手先问。

谢谢!

罗伯特

解决方法

1-使用界面查找/实现要调用的代码。出于多种原因,我更喜欢使用接口方法而不是静态方法,但是主要原因是:

a)它们可以被覆盖或轻松委派给另一个实现。

b)您可以确定使用正确的方法。

c)对于静态方法,您必须事先知道它所在的类。对于已实现的方法,您不必在意声明该方法的类是什么。许多静态方法可以具有相同的签名,但是可以做不同的事情,因为它们没有绑定到已知接口。

d)您可以将接口添加为在单独的自定义中共享的简单dll(与您的其他接口一起使用)。

e)您不会污染其他界面,因为它们是分开的。

f)您宣布自己做了什么,但没有宣布如何做。

g)接口是维护良好分离的结构的最佳方法。

h)它们是使用Strategy Pattern

时的理想选择
public interface ISomeInterface {
    object DoSomething(); 
}


OR

public interface ISomeInterface,PXGraph,new() {
    object DoSomething(); 
}

2-在任意数量的定制包中,根据需要多次实施您的界面。您的实现不必是PXGraph,但如果您希望与它共享代码或访问其他共享的代码,则可以将其实现。

public class SomeGraph : PXGraph<SomeGraph>,ISomeInterface {

       public object DoSomething() {
          do something;
          return result;
       }
}

3-然后,在任何已加载代码的某些部分中,找到您的实现并调用它们。就我而言,我使用了Post-publish界面:

public class B2BFramework : CustomizationPlugin {

    public override void UpdateDatabase() {
        var impls = B2BUtils.GetImplementations<IDataFactory>();
        foreach (var impl in impls) {
            var dataFactory = (IDataFactory)Activator.CreateInstance(impl);
            var result = factory.DoSomething();
        }
    }
}

4-这是B2BUtils.GetImplementations();

的代码
    public static IEnumerable<Type> GetImplementations<T>() {
        return GetImplementations(typeof(T));
    }

    public static IEnumerable<Type> GetImplementations(Type interfaceType) {
        var impls = new List<Type>();
        foreach (var ass in AppDomain.CurrentDomain.GetAssemblies()) {
            if (PXSubstManager.IsSuitableTypeExportAssembly(ass,true)) {
                Type[] types = null;
                try {
                    if (!ass.IsDynamic)
                        types = ass.GetExportedTypes();
                } catch (ReflectionTypeLoadException te) {
                    PXTrace.WriteError("An exception occured when loading assembly {0}: {1}",ass.FullName,te.Message);
                    types = te.Types;
                } catch (Exception ex) {
                    PXTrace.WriteError("An exception occured when loading assembly {0}: {1}",ex.Message);
                    continue;
                }
                if (types != null) {
                    foreach (var t in types) {
                        if (interfaceType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract) {
                            impls.Add(t);
                        }
                    }
                }
            }
        }
        return impls;
    }
,

您是在谈论调用包含在不同自定义项中的静态函数,还是调用另一个图扩展中的实际实例方法?

这两个选项都是可能的-您所有的自定义最终都将被编译并发布到同一文件夹(如果有DLL,则为App_RuntimeCode和bin文件夹),并且您可以安全地访问其他自定义项目中包含的代码。

如果要调用另一个图形扩展的实例方法,则首先需要在可用的情况下检索该图形扩展的实例:

var someExtension = Base.GetExtension<SomeExtension>();
someExtension?.SomeFunction();