I am doing some automation in E10 that issues material to or from a job for a specific part. I was doing this in a custom BPM Assembly called from the Update (PreProcessing) on UD01. UD01 holds the staged records ready for upload into parttran transactions.
For performance reasons (i am using threading and copied sessions to allow the UI to free up resources for other tasks) I have now moved this into a separate dll which is instantiated on the actions menu toolclick event. This is causing the following issues:
if I compile my assembly into the inetpub/wwwroot//Server/Assemblies or Externals directory I cannot reference it in the Client customization XML (it needs to be placed into LocalClient directory or the reference will not appear within assembly reference manager)
if i compile it into the client directory when the assembly is instantiated i get errors such as file not found for server dlls that are referenced in visual studio (i.e. file not found, could not load Epicor.Customization.BPM dll - are you missing an assembly reference?)
What I need to do is have this assembly on the server and reference it in customization xml or stop it whinging when it is placed into the client directory. I should not have to copy all server dlls local and deploy them to the client.
Does anybody have any experience of this type of faffing around? is there a supersearch workaround or known issue with xml referencing?
You can write the code to invoke adapters and such in the customization or you can do it in a BPM but you cannot invoke BPM code in a customization and vise versa.
If your goal is to issue material to jobs that are “staged” in UD01 you should write your code in a BPM async (so that it runs without blocking) and then simply invoke Update form the UI customization to trigger the BPM.
Also let me discourage you from creating custom DLL’s, these become version specific and every time you upgrade versions you’ll have to re-compile / re-deploy them. This is generally not necessary since most of the code( with very few exceptions) can be written directly in the BPM or customization
“I am doing some automation in E10 that issues material to or from a job for a specific part. I was doing this in a custom BPM Assembly called from the Update (PreProcessing) on UD01. UD01 holds the staged records ready for upload into parttran transactions.”
Just checking here, are you writing PartTran records into the database or using the Issue Material/Return Material adapters/business objects to process these staged records? Sounds like an interesting solution and curious about the business case.
Another option, if you want to avoid library dependencies, is to convert the solution to a RESTful one so you’re only updating your code when the method signature or the data model changes. What version are you running?
Standard coding techniques are employed for the dll, using WCFServiceSupport.CreateImpl as opposed to Ice.Assemblies.ServiceRenderer.GetService because that allows me to pass in a session object. Therefore allowing me to use Session.Copy to prevent the screen locking up when the automation takes place.
Also - i have cut out the BPM thus improving performance, as when run through the BPM it uses the base session and locks the screen when carrying out the issue process.
I am also using a background worker process for the dll asynch threading, which returns a progress update to the ultragrid.
If you look at the conversion workbench in just decompile - my code is replicating that. if that makes sense.
So rest assured, I am using epicor approved standard coding techniques, my only issue is that to reference my asynch dll in customization, it needs to be in the client directory and when it is in the client directory, it needs copies of the server dlls that it references, as above.
when i compile into the server directory, I cannot reference it in the customization xml - assembly reference manager.
Like I mentioned before you can’t run Server side code in the client. If you want to instantiate objects and such in the client context you’ll have to do it using the Client Libraries.
You are instantiating the BO’s using the client side libraries as you mentioned WCFServiceSupport which is all well and good, but if it is asking for Server assemblies is because your DLL is using some of those server assemblies, you should switch to use only client assemblies if you are looking to call it from the client.
I see you are using ERP Context to run LINQ queries on the DB which is not available in the client that would be one of the issues. The client does not (and should not) have direct access to the EF Context, if you need to get data from the database you should use BAQ’s or the adapters.
This is how the architecture is constructed, the client uses the BO’s to communicate with the server which then communicates directly with the DB.
You are combining server side code with client code and is what is causing the issues.
Look at your visual studio project and any reference dll you pulled from the Assemblies folder needs to go. You should only pull references from the client / or the server but not both.
For what is worth, you can run a BPM asynchronous which will not lock the UI. Code run on the BPM side is always more efficient than client code since it doesn’t have to make the trip over the network to make the calls.
Although I must add - the cause is essentially the client being unable to reference a server assembly.
It is all fair and well having client and server services, but for customization it would be nice to have this facility available while not restricting assembly references to those in the client directory.
If you pull all the libraries from one side (client) or the other (server) this should solve your problem. The client cannot access the Db (Context) but you can still run queries if you push them through the BAQ Engine or the BO.
EIther approach should work but whatever approach you take will have to be executed from the appropriate context. Server code from the server side (BPM) , client code from the client side (Customization)
yes - but you would not see progress updates on the client. the idea is to process each record asynchronously whilst reviewing the progress on the client.
Hence conversion workbench approach.
FYI: the solution works well. you just need to have the referenced dlls available. thus each record is processed in a separate thread and the user gets progress updates whilst creating issue / withdrawal transactions…
Even if you were able to pull in the server references (which you can do by copying them down) you would still be missing the appropriate context.
I think the issue here is one of architecture, the system is setup in such a way that the client is not meant to have direct access to the server side functions, but rather everything should be done from the client via the services (SOA)
That’s why sometimes a split approach is best, have the client do the client side processing and then invoke the server via the BO’s and BPMs to accomplish what you are looking for.
You can still do multi-threading and UI updating with this approach, just make the server calls (via the BO’s) on a background worker (like you are already doing) and still report progress as you go.
The BO coding is not setup for using threading, conversion workbench is the only form that I can see that uses the technique, thus it is impossible to start them in a background worker process or report progress.
This screen allows you to transfer multiple parts from one bin to another (“Mass Inventory Transfer”) and it reports progress / errors as it goes.
The approach is as outlined before, the customization processes each selected record one at a time in a background worker which invokes the BO’s as needed and as it progresses it updates the UI similarly to what you shared.