csharp Erik Johnson来自Epicor的BO和WCF

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp Erik Johnson来自Epicor的BO和WCF相关的知识,希望对你有一定的参考价值。


The service contract (Erp.Contracts.BO.OrderAlloc) passes a plain old class object (POCO) which Epicor derives from our own Tableset base class. We did this because it is faster to serialize these objects and there is better interoperability across platforms than with Datasets. Tablesets are just lists of lists of objects that make up the same content as a Dataset. But instead of calling Dataset methods to query or sort the data, you can use Linq to C#, which opens up a lot of other options for reuse.

All that said, our client application still data binds to Dataset fields. So the “Impl” classes (Erp.Proxy.BO.OrderAllocImpl) convert the Tableset representation to a Dataset. Both assemblies require a reference to Epicor.ServiceModel. The Impl classes have some helpers for communications (like retries) and security. The Contract classes are a little closer to the metal and use some Windows Communications Foundation libraries to execute. Here a console app example of using both…

static void TestUsingPartImpl()
{
	var wcfBinding = NetTcp.UsernameWindowsChannel();
	var appServer = new Uri("net.tcp://localhost/epicor10/erp/bo/part.svc");
	using (var partClient = new PartImpl(wcfBinding, appServer))
	{
		partClient.ClientCredentials.UserName.UserName = "Manager";
		partClient.ClientCredentials.UserName.Password = "Epicor123";
		bool morePages;
		var myPartDataset = partClient.GetList("", 10, 1, out morePages);
		foreach (var partRec in myPartDataset.PartList.Rows.Cast<PartListDataSet.PartListRow>())
		{
			Console.WriteLine(partRec.PartNum);
		}
		partClient.Close();
	}
}

static void TestUsingPartContract()
{
	var wcfBinding = NetTcp.UsernameWindowsChannel();
	var appServer = new Uri("net.tcp://localhost/epicor10/erp/bo/part.svc");
	using (ChannelFactory<PartSvcContract> cf = new ChannelFactory<PartSvcContract>(wcfBinding))
	{
		cf.Credentials.UserName.UserName = "Manager";
		cf.Credentials.UserName.Password = "Epicor123";

		var partClient = cf.CreateChannel(new EndpointAddress(appServer));
		bool morePages;
		var myPartTableset = partClient.GetList("", 10, 1, out morePages);

		foreach (var partRec in myPartTableset.PartList)
		{
			Console.WriteLine(partRec.PartNum);
		}
		cf.Close();
	}
}

Both approaches can be used in a BPM directive – it’s really a choice of which programming approach you want – basic object graphs or Datasets. Both approaches send the call through the network stack and into the server just like a call coming from a client app. Each call will have to authenticate/authorize the call, which adds some overhead.

There is apparently a better way using an internal Epicor class called the ServiceRenderer<T> where T is (I think) the actual service type (e.g. Erp.Services.BO.OrderAlloc). Using this would bypass the network stack and much of the setup/teardown code that happens when a call comes into the system. But I need some confirmation from R&D that this is actually an option and that it can work. I’m working with someone on the question, but he is on the road today. Hopefully we can get some better advice out by early next week.

-Erik

以上是关于csharp Erik Johnson来自Epicor的BO和WCF的主要内容,如果未能解决你的问题,请参考以下文章

如何从 typesafe redux-observable epic 中收听“@@router/LOCATION_CHANGE”动作

Erik Bergstedt的工具库简化了在.NET中使用Protobuf的方式

显示 GROUP BY 的所有单独行,按组的基数排序

epic的意思是啥。

为啥 Johnson-SU 分布在 scipy.stats 中没有给出正偏度?

epic是啥意思 翻译