How to re-use a user control in two Silverlight client applications? - c#

I'm kind of new to Silverlight and I have a solution which has one web project (webApp) that provides remote services and two client applications (client-1 and client-2) that uses these services.
I have created a complex user control in client-1 that view/edit an object retrieved from webApp and I want to re-use this control in client-2.
The problem is, when you reference the service from the client apps, the types are "locally-typed". For example, MyClass defined in the webApp becomes client-1.MyClass in client-1 app. Using exactly the same object (reference) in client-2 app, it is now of type client-2.MyClass
If I create a library to host my control, I will have to add a reference to the web services and I will have a third type, lib.MyClass. We all know that client-1.MyClass, client-2.MyClass and lib.MyClass are all exactly the same class that was generated from web.MyClass but I can't find a way around this problem.
I'm currently looking at sharing the source code of the user control in each client application and having pre-processor defines in each project so I can do this in my user control code file:
#if CLIENT-1
using Client-1.WebAppServiceReference
#end if
#if CLIENT-2
using Client-2.WebAppServiceReference
#end if
Then the method that uses the type MyClass are using the correct "local-type" in each client app. But I'm having problem since there is no pre-processor functionality in the xaml and there is a reference to the application's namespace there that I need to be conditional.
There's got a be an easier way of re-using controls accross silverlight projects, no?? There is no way I'm going to have two copies of the source files for this control, on in each project!!
Thanks!

There are a couple of options that allow you to use shared entity classes across Silverlight projects/WCF service proxies.
Use an RIA class library
Use a portable class library
If you create your DataContract classes with either of the above, and then reference the library from both your WCF and Silverlight client projects, then the auto-generated code will use a reference to those shared classes (rather than the locally auto-generated classes). This should allow you to re-use your Silverlight UserControls between projects.
The difference between the two approaches is this. If you use the first approach (RIA project), then when you create files named "SomeEntityClass.shared.cs", the ".shared" tells Visual Studio to place a copy of the file in a mirror Silverlight project. The second approach (PCL) is a newer approach -- it allows you to create class libraries that are capable of targeting multiple platforms (.Net, Silverlight, Windows Phone, ...), with a reduced set of core .NET libraries.

I suggest you to dissociate the XAML and graphical stuff from any of Business logics and the like. MVVM is a very good pattern to follow.
After that, you can reference your UserControl from second project with the very useful functionality of Visual Studio "Add as Link"
Here how you can do it :
For the underlying business, you can make it available for both project, and linking these 2 with it.
Hope it helps

Related

C# class with optional GUI?

I am looking for a way to have a C# class, primarily run without any sort of GUI as part of a Windows Service to optionally be displayed on a WPF Canvas control.
My initial thought was to just make the object extend a WPF Control, however this would require the server-side (Windows Service) to have those libraries referenced, which isn't ideal. My second idea was to implement a Factory pattern whereby a wrapper would generate a GUI for the object, however I'd like the object to be able to define it's own design (XAML with codebehind ideally) if desired.
These classes are loaded via MEF from a plugins directory and instantiated based on an XML-based settings file.
The possibility of just having two separate classes had also crossed my mind, but this seems to add complexity and redundancy to the plugin making process (there will likely be several of these).
Thoughts?
EDIT: The classes can be thought of as Windows Workflow Foundation Activities. They are configured via a GUI and run on a server.
Separate the "business logic" of the class itself from any GUI of it. The GUI should just be a view (possibly with interaction) on top of the business logic.
As an example, I recently gave a presentation on "Skeetris" - a block-dropping game which might look familiar to some people. I have several projects in the solution:
Two projects which everything else references:
Skeetris.Common (bits not actually specific to Skeetris - they'd normally go in a utility library in a general namespace)
Skeetris.Model (all the actual behaviour - dropping and rotating shapes etc)
Client projects:
Skeetris.Text (console-based version)
Skeetris.Wpf
Skeetris.WindowsStore
Skeetris.Email
Skeetris.Twitter
And testing projects:
Skeetris.Model.Test (tests for the model)
Skeetris.Model.Testing (a project with internal access to Skeetris.Model, designed to make it easier to test both the model and any code using the model)
As you can see, there's a wide variety of clients here - but none of them really "understand" Skeetris; only the model project does. The UI layer is as thin as possible, putting more logic into the model classes which are more easily tested.
This sort of setup sounds like an ideal fit for your project too:
A "core" business logic project
A Windows Service adapter project (with the code to respond to service events)
A WPF project
Test projects, of course :)
4sak3n0ne,
For this sort of requirement your best scenario would be using a minimum of 3 projects to achieve this result. You would have the following project system hierarchy.
MyApp.Logic <- This is where your common class libraries are created.
MyApp.Service <- This is your windows service library.
MyApp.GUI <- This is your WPF GUI project.
Now given the project hierarchy (probably more and advanced than this) I would then reference the MyApp.Logic to both the MyApp.Service and MyApp.GUI projects.
This gives you clear separation between your logic, front end gui and windows service while still using the same code base. This also makes it easier to understand what each part of your solution does and allows for re-use of the same logic code base.
Cheers.

How to configure Silverlight + CSLA Data Portal?

I am new to Silverlight and CSLA and I need to get an example project working. I have both Lhotka's 2008 book on CSLA, as well as the Silverlight ebook + example project it comes with.
I thought it would be fairly simple to create a Silverlight 5 MVVM Light project that grabs a CSLA 4.3 object through the Data Portal (data portal/channel adapter configured to use WCF) but can't get a CSLA object back from the Server.
NOTE: If I take CSLA out of the equation and just use Linq to SQL or Entity Framework and a WCF RIA Service call I can grab objects from the server and display them in silverlight just fine, but as I can't use that on this project I must get CSLA to work.
My steps:
Created a Silverlight Business Application - get a MyProject (SL) and a MyProject.Web (WCF)
Added a service to the .Web project
<% #ServiceHost Service="Csla.Server.Hosts.Silverlight.WcfPortal" %>
.
Referenced the Service in my App.xaml Application_Startup method in the SL project
Csla.DataPortalClient.WcfProxy.DefaultUrl = "http://localhost:14790/Services/MyTestCslaSilverlightWcfService.svc";
.
Added a simple CSLA Business layer project (MyProject.CSLA) that has one set of test objects (MyMobileObjItem.cs, MyMobileObjItemList.cs)
Added two more projects (MyProject.CSLA.Client and MyProject.CSLA.Server). The .Client project is a Silverlight class library, the .Server is a class library. I then linked all my CSLA objects (add existing reference, add as link) plus all necessary references (csla/csla silverlight dlls). On MyProject I add a reference the .Client project and on MyProject.Web I add a reference to the .Server project.
Now I should have a working project, and want to get an item or a list of items back from the server. In my main ViewModel in the constructor I have tried two different things. When I use
MyMobileObjItemList.GetAllAsync(HandleReturnedArgs);
the callback method EventArgs have an error "System.IO.FileNotFoundException: Could not load file or assembly "MyProject.CSLA.Client". I find this weird since the Silverlight app has a reference to this project, and the MyProject.Web shouldn't need the .Client reference since it has the .Server reference.
When I use
DataPortal<MyMobileObjItemList> dp = new DataPortal<MyMobileObjItemList>();
dp.FetchCompleted += HandleReturnedArgs;
dp.BeginFetch();
the callback method EventArgs have an error "System.InvalidOperationException: Object type or assembly could not be loaded (MyProject.CSLA.MyMobileObjItemList, MyProject.CSLA.Client".
I am not sure where either of these errors are happening (on the client or server?) Since it is a Csla.DataPortalException I assume it is a server error.
I am not sure how to do a simple call or if this is the correct way of going about things as all the examples I can find don't do it this way and seem unclear to me.
I know this is a lot of pieces to fit together and it may be hard to concisely give an answer, but I really would appreciate help (code, link to download example etc.)
QUESTIONS:
Is there a simple example of Silverlight MVVM Light project that calls a remote data portal that grabs object(s) along with documentation of how to get it to work/how all pieces fit together? Again, I have the ebook Silverlight project, but that uses bxf and most of the data portal references the book has just says to see the other ebook on data portals (which I don't have - I would buy it but the site takes a couple days to allow access to the pdf. Really poor site). OR
Can someone explain what I am doing wrong?
To fix the error error I changed the assembly and default namespaces for my .Client and .Server projects to exactly match the .CSLA project (set in project properties)
See this forum discussion for more info

Why do I have to create a Service Reference to the WCF within my WPF?

I've browsed around for an answer, but I haven't found anything that really says, 'Hey dummy, this is what's up.' So, I have a WPF application that references a Class library, within the Class library I create connections to and call WCF applications and it works fine. The issue is that I have to create a service reference within my WPF in order for the program to work, even though the WPF doesn't directly interact with the WCF applications at all. If you need any more info, or if you have any advice, please let me know. Thank you for your time.
You don't have to, the only thing you need in the WPF application is the settings in the app.config under <system.serviceModel> from the class library's app.config.
The settings file used in a project is the executing one, so when you added the reference also to the WPF application it created an entry for <system.serviceModel> in your WPF app.
Have a look at this example of creating a dynamic proxy
The reference you need to set is probably needed because you are using (generated) classes that implement interfaces or inherit from classes in that assembly.
A generated proxy inherits from

Class Libraries, Silverlight and Webservices

I have a Silverlight Class Library that I want to use in both my Silverlight and my WebService project.
I am able to create and reference the Library in both projects without any problems, but when I try to use any of the classes in the Library on the Silerlight project, I get an ambiguous reference error between my Library and the Asmx Webservice (apparently, the silverlight project believes that the classes in the class library exist in the webservice).
How can I correct this issue? I have tried rebuilding and cleaning, but it does not seem to work. Can anyone help?
Sounds like the objects you are passing to Silverlight, via the WCF service, are the same objects in your class library. In that case the generated web-reference objects will be given the same names. Linking with the library will then give you 2 sets of objects with the same names.
If you install RIA services, once feature is the ability to share code between client and server by simply adding ".shared" in the class filenames before the extensions. ASMX services are so last century :)
if you don't want to learn the RIA services way of sharing objects across the great-web-divide (which I would recommend), you need to separate the data objects from the functionality you actually want to share client and server side.
To give more specific advice on your current set-up I would need to see more about how it is structured.
A technique you can use is aliasing your using statements:
using MyNameSpace = My.Name.Space;
using MyWebService = My.Web.Service;
Then access all of your objects with these aliases to remove the ambiguities.

Problem sharing domain model between WCF and Silverlight Project

I am writing a Large Scale Silverlight Application.
I am currently writing the data retrieval elements.
I have now encoutered and issue.
I have a common Project that hold objects, this project is referenced by both the UI and the WCF service.
The UI requires INotifyPropertyChanged for binding purposes.
Now the WCF must use the same objects, but I am getting a compiler error saying
"The type
'System.ComponentModel.INotifyPropertyChanged'
is defined in an assembly that is not
referenced."
EDIT: The error is in the WCF service.
I want one object class, how do I solve this problem?
diagram http://www.pcbuyersguide.co.za/picture.php?albumid=19&pictureid=1708
Thanks
-Oliver
If you plan to use the same source code for your Entities (domain) for both a clr and silverlight project you will need to use 2 projects because the Silverlight assemblies are not the same as CLR assemblies.
Add a Silverlight Class Library project to your solution, the name is not important but I usually just use XXXX_SL.
Now, you will 'Add Existing Item' all of the source files from the clr project, but notice the dropdown on the open or select button? click that and 'add as link' or whatever it says there.
You are now using the same source for both projects and your solution will compile.
There may be some minor tweaks along the way but that will set you on the right path..
Here is some reference material
did you add a reference in the compiling project to System.ComponentModel
I found a method here that allows one to create the CLR classes on the service side and then one can use the generated objects from the Service Reference as the classes are generated with the INotifyPropertyChanged and ObservableCollection.
This solves the immediate problem of the client/server boundary but does fit into my solution because in order to use the generated objects you need the service reference. But I have a ProxyClass that does the talking to WCF so there I cannot see a way of passing these object types back to the ViewModel.
I see some people have written mapper classes, but this is far from ideal as I would have to write 3 classes for each POCO object (client class, server DTO class, mapper).
Any more suggestions?

Categories

Resources