Thanks for playing. We had some victims - but they weren't brave enough to post on this topic and opted to email or telephone for confirmation first - cheaters! You know who you are
==============================================
Exciting new changes for Plugin Developers for Jiwa!
As you know, we currently support both C# and VB.Net languages for plugins within Jiwa.
We've seen in our ongoing poll that there is a fairly even split between the language preference (50% C#, 50% VB).
We try as best we can to gauge the language preference you have based on your post and your previous posts - and as such always try to provide any sample code or plugins here based on what we think you'd prefer (we also state in a huge sticky post that you explicitly tell us in your post what language you prefer so we can accommodate, but that's usually ignored so we apply heuristics in those cases).
Sometimes we have already built stuff in the past which would answer your question, but it's not in your preferred language - so we're left with either spending the time ourselves converting from one language to another, or just posting you some code or plugin in your non-preferred language and leaving the conversion up to you.
Some of you don't like C# and some like VB.Net - we get that and whilst we try to be as inclusive as we can with our samples, responses to posts and documentation - we know we're not always keeping everyone happy all of the time in respect to language preference.
Well - do we have some good news for you!
As you may well know, all .Net languages compile down to what's known as the CIL - this is a bytecode-like format known as Common Intermediate Language (CIL or previously MSIL). So whether you write in C# or VB.Net, the compiler creates the IL code and that is what is executed by the .Net runtime.
We've done some research and development and testing and we're pleased to announce our support for CIL/IL/MSIL for plugins!
Rather than introduce yet another language to support in plugins, we've decided the way to settle the language wars and be totally inclusive is to only support CIL in plugins - so no more C# or VB.Net - just CIL.
This brings so many benefits, but to list just a few:
* Rapid plugin compilation - there actually is none! it's instant!
* No more language barriers / wars or conversions!
* No need to worry about how the compiler optimises your code! It's run as it is!
* Reduced overhead in providing samples and documentation - it's all just CIL!
Your existing plugins, of course, will no longer work and need to be converted to CIL - but fortunately there is some tooling to do that for you without much effort. We'll get back to that later in this post - but first let's have a look at what a plugin looks like when written in CIL.
So, to take an example of a plugin most recently posted here by myself - the code (in C#) looks like this:
- Code: Select all
public class BusinessLogicPlugin : System.MarshalByRefObject, JiwaFinancials.Jiwa.JiwaApplication.IJiwaBusinessLogicPlugin
{
public void Setup(JiwaFinancials.Jiwa.JiwaApplication.IJiwaBusinessLogic JiwaBusinessLogic, JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin Plugin)
{
JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin newPlugin = (JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin)JiwaBusinessLogic;
newPlugin.CreateEnd += delegate(object sender, System.EventArgs e)
{
if(newPlugin.Language == JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin.Languages.VisualBasic)
newPlugin.Code = "Imports System" + System.Environment.NewLine + newPlugin.Code;
};
}
}
And in CIL the equivalent is:
- Code: Select all
.class public auto ansi beforefieldinit BusinessLogicPlugin
extends [mscorlib]System.MarshalByRefObject
implements [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.IJiwaBusinessLogicPlugin
{
.class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1'
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field public class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin newPlugin
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method '<>c__DisplayClass1'::.ctor
.method public hidebysig instance void
'<Setup>b__0'(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// Code size 61 (0x3d)
.maxstack 4
.locals init ([0] bool CS$4$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin BusinessLogicPlugin/'<>c__DisplayClass1'::newPlugin
IL_0007: callvirt instance valuetype [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin/Languages [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin::get_Language()
IL_000c: ldc.i4.0
IL_000d: ceq
IL_000f: ldc.i4.0
IL_0010: ceq
IL_0012: stloc.0
IL_0013: ldloc.0
IL_0014: brtrue.s IL_003c
IL_0016: ldarg.0
IL_0017: ldfld class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin BusinessLogicPlugin/'<>c__DisplayClass1'::newPlugin
IL_001c: ldstr "Imports System"
IL_0021: call string [mscorlib]System.Environment::get_NewLine()
IL_0026: ldarg.0
IL_0027: ldfld class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin BusinessLogicPlugin/'<>c__DisplayClass1'::newPlugin
IL_002c: callvirt instance string [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin::get_Code()
IL_0031: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_0036: callvirt instance void [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin::set_Code(string)
IL_003b: nop
IL_003c: ret
} // end of method '<>c__DisplayClass1'::'<Setup>b__0'
} // end of class '<>c__DisplayClass1'
.method public hidebysig virtual instance object
InitializeLifetimeService() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init ([0] object CS$1$0000)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method BusinessLogicPlugin::InitializeLifetimeService
.method public hidebysig newslot virtual final
instance void Setup(class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.IJiwaBusinessLogic JiwaBusinessLogic,
class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin Plugin) cil managed
{
// Code size 45 (0x2d)
.maxstack 3
.locals init ([0] class BusinessLogicPlugin/'<>c__DisplayClass1' 'CS$<>8__locals2')
IL_0000: newobj instance void BusinessLogicPlugin/'<>c__DisplayClass1'::.ctor()
IL_0005: stloc.0
IL_0006: nop
IL_0007: ldloc.0
IL_0008: ldarg.1
IL_0009: castclass [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin
IL_000e: stfld class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin BusinessLogicPlugin/'<>c__DisplayClass1'::newPlugin
IL_0013: ldloc.0
IL_0014: ldfld class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin BusinessLogicPlugin/'<>c__DisplayClass1'::newPlugin
IL_0019: ldloc.0
IL_001a: ldftn instance void BusinessLogicPlugin/'<>c__DisplayClass1'::'<Setup>b__0'(object,
class [mscorlib]System.EventArgs)
IL_0020: newobj instance void [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.IJiwaCreatable/CreateEndEventHandler::.ctor(object,
native int)
IL_0025: callvirt instance void [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.BusinessLogic.Maintenance::add_CreateEnd(class [JiwaApplication]JiwaFinancials.Jiwa.JiwaApplication.IJiwaCreatable/CreateEndEventHandler)
IL_002a: nop
IL_002b: nop
IL_002c: ret
} // end of method BusinessLogicPlugin::Setup
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.MarshalByRefObject::.ctor()
IL_0006: ret
} // end of method BusinessLogicPlugin::.ctor
} // end of class BusinessLogicPlugin
As you can see - the operations are pretty straightforward and self-explanatory. The best part is you don't need to mentally compile C# or VB.Net in your head to see what's happening - PLUS - you don't need to worry about a pesky compiler having opinions on how to optimise the code! It's win-win!
It goes without saying this means that intellisense, autocomplete and error checking or warnings are no longer possible or available - but we think the benefits far outweigh this minor inconvenience.
How to convert your existing plugins:
It's really simple - just locate an already compiled plugin assembly in the %programdata%\Jiwa Financials folder and run ILDASM against it to generate the IL code:
- Code: Select all
C:\ProgramData\Jiwa Financials\Jiwa 7\7.2.0\mikes\localhost\JiwaDemo720\Plugins\Admin\Runtime\Imports System>ildasm "Imports System.dll" /out=converted.il
In the above, a file - converted.il - is output containing your output code - conversion done! How painless was that?!