Nous avons une initiative où nous devons avoir une communication entre deux packages de personnalisation distincts. Nous avons donc la personnalisation A qui doit appeler une méthode qui est la mieux adaptée pour être mise en œuvre dans la personnalisation B.Mes pensées à ce jour sont de configurer un WebHook puis d'appeler la fonction dont nous avons besoin en engageant directement le webhook à partir de la personnalisation A. Avant de continuer avec la mise en œuvre de cela, je voulais tendre la main pour voir comment d'autres ont résolu cette exigence. Est-il possible d’appeler des fonctions à partir d’autres personnalisations directement dans C #. Mais je voulais tendre la main et demander d'abord.

Merci d'avance!

Robert

1
Robert Waite 27 août 2020 à 16:11

2 réponses

Meilleure réponse

1- Utilisez une interface pour localiser / implémenter le code à appeler. Je préfère les méthodes d'interface plutôt que les méthodes statiques pour plusieurs raisons, mais les principales raisons sont:

A) Ils peuvent être remplacés ou facilement délégués à une autre implémentation.

B) Vous pouvez être sûr que vous utilisez la bonne méthode.

C) Pour les méthodes statiques, vous devez connaître au préalable la classe dans laquelle elle se trouve. Pour les méthodes implémentées, vous ne vous souciez pas de la classe dans laquelle la méthode est déclarée. De nombreuses méthodes statiques peuvent avoir la même signature mais font des choses différentes puisqu'elles ne sont pas liées à une interface connue.

D) Vous pouvez ajouter l'interface en tant que simple dll partagée dans une personnalisation séparée (avec vous d'autres interfaces).

E) Vous ne polluez pas vos autres interfaces car elles sont séparées.

F) Vous annoncez ce que vous faites mais pas comment vous le faites.

G) Les interfaces sont le meilleur moyen de maintenir des constructions bien découplées.

H) Ils sont idéaux lorsque vous utilisez le modèle de stratégie

public interface ISomeInterface {
    object DoSomething(); 
}


OR

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

2- Implémentez votre interface autant de fois que vous le souhaitez dans autant de packages de personnalisation que vous le souhaitez. Vos implémentations n'ont pas besoin d'être un PXGraph, mais elles le peuvent si vous souhaitez partager du code avec lui ou accéder à d'autres morceaux de code partagés.

public class SomeGraph : PXGraph<SomeGraph>, ISomeInterface {

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

3- Ensuite, dans certaines parties de tout code chargé, trouvez vos implémentations et appelez-les. Dans mon cas, j'ai utilisé l'interface Post-publication:

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- Voici le code pour 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}", ass.FullName, ex.Message);
                    continue;
                }
                if (types != null) {
                    foreach (var t in types) {
                        if (interfaceType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract) {
                            impls.Add(t);
                        }
                    }
                }
            }
        }
        return impls;
    }
2
Stéphane Bélanger 31 août 2020 à 04:06

Parlez-vous d'appeler une fonction statique incluse dans une personnalisation différente, ou d'appeler une méthode d'instance réelle qui se trouve dans une autre extension de graphique?

Les deux options sont possibles - toutes vos personnalisations finissent par être compilées et publiées dans le même dossier (App_RuntimeCode et les dossiers bin si vous avez des DLL), et vous pouvez accéder en toute sécurité au code contenu dans un projet de personnalisation différent.

Si vous souhaitez appeler une méthode d'instance d'une autre extension de graphe, vous devrez d'abord récupérer une instance de l'extension de graphe là où elle est disponible:

var someExtension = Base.GetExtension<SomeExtension>();
someExtension?.SomeFunction();
1
Gabriel 27 août 2020 à 18:40