[AX]AX2012 使用Proxy Class for .NET Interop to X++

除了使用.NET Bussiness connector从C#工程访问AX的数据及方法,还可以使用Proxy Class for .NET Interop to X++功能直接将X++的类、表转化成C#的代理类,在.NET项目中使用代理类码更加直接的访问AX。相比较.NET Bussiness connector,前者使用后绑定编程模型,而Proxy class使用前绑定编程模型,在Visual studio的代码编辑窗口中可以得到相关方法的智能提示,所以在一些情况下Proxy class可以更好的替代.NET Bussiness connector。AX的Class、Table和Enum可以转化成C#类,步骤非常简单,以CustTable表为例:

首先需要创建一个C#的Class library工程,并添加到AOT,在把工程添加到AOT时Class library工程的引用中自动添加了Microsoft.Dynamics.Ax.ManagedInterop程序集,打开Application explorer,找到CustTable表,右键单击“Add to project”就可以了,在solution explorer中同时多了一个CustTable,我们是看不到其相应的代码的,但是在代码中使用它的方法及字段:

public class Class1
    {
        public string GetCustomerPaymentMode(string accountNum, string dataAreaId)
        {

            string paymentMode = String.Empty;
            CustTable custTable = new CustTable();

            // Search for the customer.
            custTable = CustTable.findByCompany(dataAreaId, accountNum);

            if (custTable.Found)
            {
                // Get the value for the customer's payment mode.
                paymentMode = custTable.PaymMode;
            }

            return paymentMode;
        }

        public bool GetCustomerCreditLimit(string accountNum, string dataAreaId)
        {

            bool hasCreditLimit = false;
            CustTable custTable = new CustTable();

            // Search for the customer.
            custTable = CustTable.findByCompany(dataAreaId, accountNum);

            if (custTable.Found)
            {
                // Get the value for whether the customer has a credit limit.
                hasCreditLimit = (custTable.MandatoryCreditLimit == NoYes.No ? false : true);
            }

            return hasCreditLimit;
        }

这里的CustTable.findByCompany就是表CustTable的X++静态方法public static CustTable findByCompany(),在C#中我们可以很方便的直接使用它。有了这个Class library,我们可以在其他的工程中来使用它,所有的代理类内部都继承自Microsoft.Dynamics.AX.ManagedInterop.Object,因此需要在相应工程中添加对程序集Microsoft.Dynamics.AX.ManagedInterop的引用,在默认安装目录C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin下。和使用.NET Bussiness connector一样,由于程序集是2.0 runtime的混合模型程序集,所以需要把Class library及引用它的工程target都设为.NET Framework 3.5,或者target .NET Framework 4.0的工程中在app.config添加<startup useLegacyV2RuntimeActivationPolicy="true">。可以这样使用Class library来间接的使用CustTable的proxy class:

using (Session session = new Session())
            {
                session.Logon(null, null, null, null);

                Class1 class1 = new Class1();
                string accountNum = "3003";
                string dataAreaId = "ceu";
                string paymentMode = String.Empty;
                string hasCreditLimitText = String.Empty;
                bool hasCreditLimit;

                // Get the customer payment mode and credit limit.
                paymentMode = class1.GetCustomerPaymentMode(accountNum, dataAreaId);
                hasCreditLimit = class1.GetCustomerCreditLimit(accountNum, dataAreaId);
                hasCreditLimitText = (hasCreditLimit == false ? " and does not have" : " and has");

                // Write the data to the console
                MessageBox.Show("Customer " + accountNum + " in company " + dataAreaId +
                    " has a payment mode of " + paymentMode + hasCreditLimitText +
                    " a mandatory credit limit.");
            }

Session类型来自于命名空间Microsoft.Dynamics.AX.ManagedInterop,可见仍然是需要首先登陆连接到AX系统才能后续操作。

对X++对象的方法还可以使用C#添加事件处理,比如X++定义一个类:

class MyClass
{
    public void myMethod()
    {
        info("MyClass.myMethod called.");
    }
}

使用一个X++的JOB来调用MyClass.myMethod方法:

static void callMyClass(Args _args)
{

    MyClass myClass;
    myClass = new MyClass();

    myClass.myMethod();

}

可以创建一个C#的类来捕捉myClass.myMethod()调用前和调用后的事件,和前面一样同样需要一个C#的Class library工程并添加到AOT,在工程中添加一个public类MyPostEventHandler来接收事件,保持MyPostEventHandler在代码编辑窗口中打开状态且编辑光标位于MyPostEventHandler的括号内,打开Application exlporer找到MyClass的myMethod方法,右键点击我们看到“Add pre-event handler”和“Add post-event handler”两个选项,这里测试“Add post-event handler”,在VS中会自动添加一些代码到MyPostEventHandler:

public class MyPostEventHandler
    {

        // Do not change the name of the event handler method. If you rename the method, the event handler will not work.
        [Microsoft.Dynamics.AX.ManagedInterop.XppClassDefiningEventAttribute(@"\Classes\MyClass")]
        static public void PostMyMethod(XppPrePostArgs args)
        {
            // Write an entry to the X++ InfoLog.
            Global.info("MyPostEventHandler.PostMyMethod called");
        }
    }

这里的PostMyMethod及其特性是自动添加的,Global.info(....)则是我们调用X++的Global类的info方法来在AX的Client中在探测到myClass.myMethod方法调用后显示消息。其实VS在背后还做了很多动作,它会添加XppPrePostArgs类到我们的工程,还会在AOT的MyClass.myMethod节点下添加一个名为EventHandlerSubscription1 事件订阅,将工程的“Deploy to client”和“Deploy to server”属性都设为true。要使在C# class library中的MyPostEventHandler的PostMyMethod方法得到调用,还需要编译和部署class library,Server的默认部署路径在C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\Bin\VSAssemblies\,如果没有启用程序集的Hot swapping,那还需要重启AOS,client的默认部署路径在C:\Users\ <YourUserName> \AppData\Local\Microsoft\Dynamics AX\VSAssemblies\,同样需要关闭再打开AX client才能使class libary dll得到调用。现在就可以在AX测试运行

callMyClass job了,得到的结果是info出来两天消息,一条来自于X++的myClass.myMethod,另外一条则来自于C#的MyPostEventHandler.PostMyMethod。

要调试C#的EventHandler有两种方法,第一种是在Visual studio中Debug attach到Ax32.exe,在AX中运行callMyClass job会自动跳转到EventHandler的断点,第二种是把c# class libarary工程的Target属性设置为client,Startup elment设置为Jobs\callMyClass,在VS中调试运行会自动Attach到AX Client并执行callMyClassJob。

可以看到微软把AX和Visual studio在.net平台上做了深度的整合,使得使用C#扩展AX功能变得更加的方便。更多内容见http://msdn.microsoft.com/en-us/library/gg879799

 

 

posted @ 2012-09-13 08:35  断水流  阅读(958)  评论(0编辑  收藏  举报