I'm developing a .NET application that will have both a WinForms and a Silverlight client. Although the majority of code will be in the server, I'll need to have quite a bit of logic in the clients as well, and I would like to keep the client library code the same.
From what I could figure out so far, I need to have two different project types, a class library and a Silverlight class library, and link the files from one project to the other. This seems kind of lame, but it works for simple code.
My problem, though, is that the code generated by the SVCUtil.exe to access WCF services is different from the code generated by the slsvcutil.exe, and the silverlight code is actually incompatible with the .NET one: I get a bunch of problems with the System.ServiceModel.Channel classes when I try to import the class into .NET.
Has anybody done anything similar to this before? What am I doing wrong?
Unfortunately, as of Silverlight 3 and .NET 3.5sp1, there is no binary compatibility. You must share files, and maintain two separate libraries.
Silverlight 4 and .NET 4, however, will provide some level of binary compatibility. Depending on which assemblies you use in your client side, you may be able to use the same component in both Silverlight and Windows Forms.
I know it's too late to provide a solution but it was my problem too and I found Portable Class Libraries. It's a perfect solution to your issue.
Don't try and share a single proxy client amongst disparate clients - generate a proxy per client.
You can reuse the data classes between the projects using the add as link method you described. If a new version of the classes is created in the proxy, then you can just edit the generated proxy code files and delete out the class definitions. When you compile this up each client (Windows app and silverlight) will have its own version of the compiled class library, but it is all coming from the same source code.
Related
I have a class library that targets .net 4 and is used across different platforms via Mono.
I now want to port it to be used by Windows 8. I know the name keeps changing but this is currently called a "Class Library (Windows Store Apps)" in VS2012.
I initially started with trying to port everything to a "Portable Class Library" but this was proving too difficult as some things simply didn't have a generic approach that would work on all platforms targeted, and other things that were supported simply weren't available to the compiler.
So I've created a Windows Store Class Library and created links to the existing files of my standard Class Library so updating once will update both. I am planning on using pre-processing directives to make changes between the two class libraries
E.G
#if NETFX_CORE
Task.Delay(someTime);
#else
new System.Threading.ManualResetEvent(false).WaitOne(sometime);
#endif
My question is if this method seems a sensible approach? I have the same default namespace and assembly name. Could this ever cause issues to my compiler? The assemblies target different platforms so would never be used together in the same application but do both sit in the same solution in Visual Studio.
Overall, yes that should work. That specific case is a poor example, because the two implementations function very differently, illustrating that you may need to rethink some aspects of your design. For cases where there is a similar API swap (with similar semantics), I personally tend to move the difference behind a helper method, so my "main" code doesn't need to worry about this - just the helper code. Reflection would be a good example of this (the changes to reflection are annoyingly deep).
The two projects with different target platforms should be fine. I occasionally hit an IDE glitch where it complains about temp files. I think this is due to sharing files between projects. I've logged it on connect
Try
Task.Delay(msDelay).Wait()
I'm (again and still) trying to consume some WCF services in Monotouch.
First approach: add a web reference in Monodevelop failed. It cannot create the reference file.
Then I tried SVCUTIL.EXE and get an error that the generic ChannelFactory is not available in Monotouch - I suppose because there is no reflection available.
Next I tried SLSVCUTIL.EXE from the Silverlight 3 SDK. This generates namespaces for the various services that differ from those created through SVCUTIL.EXE. As I have already lots of wrapper code I have to change a lot.
These questions arise:
Can I override the CreateChannel methods and return specialized channels for each service instead of being dependent on the non-existing generic version, as proposed by the exception that gets thrown? This means fixing the code generated by SVCUTIL.EXE.
How do I create a channel in an overridden method? I only have interfaces of my services. I googled and could not find any examples. What does code look like that has to be written in that method?
Totally unclear to me: what is the difference between the two service utilities?
If I get the namespace issue sorted out, will the stubs created through the Silverlight utility make my project work, or will that also suffer from the generic channel issue?
why can the Silverlight tool work without dynamically emitting code? What is the difference in the outputted code and what advantage does the dynamic version have?
which version of Silverlight is supported int MT. Can I use the tool of v4 or does it have to be version 3?
Does WCF in MT support streaming, like downloading large files?
WCF is a huge beast and it's very difficult to give general answers on it, too much depends on details. The general rule is that MonoTouch supports the same subset of WCF that was shipped with Silverlight (even if a few additions were made over time).
I suppose because there is no reflection available.
Reflection is available and works with MonoTouch. Reflection.Emit does not since Apple does not allow JIT'ing code on iOS devices. This can limit some API that requires code generation at runtime (but is not an issue if the code generation can be done at compile time).
... This means fixing the code generated by SVCUTIL.EXE. ...
Fighting/editing generated code is usually a bad idea (e.g. future maintenance). I suggest you try to use slsvcutil.exe before investing too much time in customizing the generated code.
... What does code look like that has to be written in that method?
The full source code for Mono's System.ServiceModel and System.ServiceModel.Web are available if you wish to provide your own channel (or customize the generated code).
Totally unclear to me: what is the difference between the two service utilities?
The SL prefix, in slsvcutil.exe, is for Silverlight. Microsoft made this tool to generate code that will only use the WCF subset available in Silverlight. Since this is the same subset supported by MonoTouch this is the best tool to use.
If I get the namespace issue sorted out, will the stubs created through the Silverlight utility make my project work, or will that also suffer from the generic channel issue?
It should work. That's how people are using (the available subset of) WCF with MonoTouch today. If there are issues with this (subset/tool) you can fill a bug report about it (with a test case) and we'll have a look at it.
Does anyone know how to do this? I built a backend c# class in asp.net but want to access these same classes without recreating them in silverlight. Is this a possibility?
You can reuse the cs files by adding them to your project AS LINK. Right click in your project and select Add Existing...Browse to your file and in the Open Button, use the pulldown arrow on the right to select Add As Link. You will see the file added to your project with an icon that with the little Windows Shortcut icon overlayed on it.
Just remember - the ASP.Net runs on the .Net runtime. Silverlight runs on the CoreCLR (Silverlight runtime.) Not everything that compiles in oone will compile in the other...
To separate things a little bit, #if directives can help, you can also use Partial Classes and partial methods (to add content that only runs on the server or on the client.)
RIA Services is definitely the way to go for sharing code between ASP.Net and Silverlight.
As well as the previously mentioned generation of domain service models, it also lets you share individual files between the web-app and Silverlight by simply inserting "shared" in to the filenames. e.g. "MyClass.shared.cs".
RIA services does not take long to get to terms with (and there are good tutorials about). Try this one.
Well, ASP.NET itself isn't going to work (ditto many of the full libraries), but I'm assuming you just mean you local domain model etc.
IIRC you can try to simply reference it, but it may well generate a warning message. Of course you need to be exceptionally careful not to use anything that the other platform doesn't support...
IMO, the better option here is to create a second csproj that includes the same .cs files (or cheat with a wildcard/deep include). And build both. Same C#, different dll/platform.
Is isn't uncommon to find that you need a very small usage of #if directives, too.
WCF RIA Services may help you solve your problem. Silverlight does not use the same runtime as ASP.Net does and you cannot directly share assemblies containing model classes on the client and the server side. To solve that WCF RIA Services will transparently generate classes on the client side based on model classes on the server side. Obviously WCF RIA Services will also allow you to create, read, update and delete objects of these classes using a web service.
MSDN has more specific information about WCF RIA Services Client Code Generation.
As an ASP.NET developer, I'm used to working with how VS/C# transparently autogens proxy classes for web references via wsdl.exe (yes, I know, we're spoiled), but now that I'm creating documentation for more than one coding platform I'm trying to discover what the equivelant to that is in any other framework.
So is there a similar way to work transparently with web reference proxy classes for say, RoR, PHP, and Python?
And if there's nothing integrated, are there tools you recommend to autogen the proxy classes, or do you recommend to roll custom classes?
I've had (limited) success with ZSI http://pywebsvcs.sourceforge.net/ for Python. Try at your own risk.
If it would be possible to run IronPython or IronRuby I would check that out.
I definitely know how VS can spoil you.
I have some VBA code that needs to talk to a running c# application.
For what it's worth, the c# application runs as a service, and exposes an interface via .net remoting.
I posted a question regarding a specific problem I'm having already (From VB6 to .net via COM and Remoting...What a mess!) but I think I may have my structure all wrong...
So I'm taking a step back - what's the best way to go about doing this?
One thing that's worth taking into account is that I want to call into the running application - not just call a precompiled DLL...
In the past, one way I accomplished something similar was with Microsoft Message Queueing. Both languages/platforms can read/write to a queue.
In my scenario, we had a legacy Access database that we had to maintain. We wanted to migrate away from it and replace it with a more robust .NET solution. To get real time data out of the current system into the new system, we added VBA code to write data to a message queue. Then we wrote a C# windows service to process that data in the new system.
I'm not entirely sure of what you're doing, so this may not be a fit, but I thought I'd mention it.
I've come up with a solution using my original structure...
That is, the VBA application calls a COM wrapper application that translates all of the types from .Net to COM safe types. This wrapper then calls the main service using .net remoting.
The problem I was having was that the common dlls between the wrapper and the service needed to be in the C:\Program Files\Microsoft Office\Office12 folder (along side msaccess.exe).
While I was using the AssemblyResolve method to provide the dlls at runtime, this wasn't working...So for now I'll just have to have the dlls copied to the folder - a far from elegant solution, but at least the communication is working for now.