Greetings,
We have built an extensive system and data framework api using interfaces and DI. For the data access, if the application is a Windows service/WCF service then a LINQ implementation of the repositories is injected at runtime using Castle. Client web/winform applications use the same Data controllers/domain objects but the implementation portions use injected WCF client classes for data access. The cool part about this setup is that the client and server code can reuse the same domain objects, services and system logic by including the appropriate assembly with a few translations.
I have just now created a Silverlight application using the "Silverlight Navigation Application" template in VS2010. It seems the only way I can reference my desktop CLR code is via linked classes (add existing item/linked). There is not a boat load of plumbing classes, but there are some core classes that handle routing interfaces for emails, SMS messages, logging, and data access using the castle microkernel and application configuration files.
I can do grid displays and whatnot by binding the controls to the WCF service references. However, I would like to reuse the controller model for messaging, data access, logging and so on. I cannot determine if it is worth the time to try to fit all the existing classes into SL project classes or start thinking about somehow creating a new lightweight api for SL? Has anyone had experience with unity/castle and Silverlight?
In regards to "It seems the only way I can reference my desktop CLR code is via linked classes" you could always use a portable class library and it will work on everything from CLR, SL through to Xbox360.
Related
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
We have developed an application in C# .NET that synchronises data (customers, orders) to a PHP e-commerce application using SOAP.
The WSDL of the PHP application is added as a .NET 2.0 web reference to our application, so the .NET Framework generates classes and functions to communicate with the SOAP web service.
For instance, we are able to send stock information like this:
catalogInventoryStockItemUpdateEntity stock = new catalogInventoryStockItemUpdateEntity();
stock.is_in_stock = 1;
stock.is_in_stockSpecified = true;
stock.qty = "10";
webserv.catalogInventoryStockItemUpdate(sessionid, itemcode, stock);
This works fine, however we are frequently running in situations where one of our customers has additional (non standard) fields defined in the WSDL and wants this fields to be used in the synchronisation.
Our current practice is to create a new branch of our code for this customer and update the web reference to use the specific WSDL of our customer.
To prevent us from getting a long unmaintanable list of branches of our software, I'm planning to do a complete overhaul of the structure of our application.
Now I am wondering what would be the best structure to handle this. I was thinking to put the web reference in it's own class and load this DLL dynamically, so if a customer has a non-standard WSDL we could create it's own class and load it as a 'plug-in' into our software. But the additional fields in (for instance) the catalogInventoryStockItemUpdate will then still not be available in the main part of our application.
Are there any tools that might help in achieving this? I would like to have one main application for synchronisation and put all customer specific mappings and references to the WSDL in a separate class/project.
First of all, for adding plugins support to your app you can use Microsoft Extensibility Framework (MEF). If you're constrained to using .NET 2.0, then there are other custom ways for discovering and loading up plugins (through separate app domains, or by loading them straight to the primary app domain).
As for the design, I would make each plugin:
Hold the service reference to it's particular web service instance.
Make any particular assignments or logic to that service. For example assign 10 to stock.qty.
Provide callbacks/events the application could use to interfere with the logic implemented in the plugin. For example, you could have the plugins expose an event called BeforeStockSubmitted and you could do some validation or checks in the app on the data being submitted to the service.
Your plugin host (the application, or a module of it) should:
Expose a consistent object model for all plugins. You should offer a certain degree of abstraction for all entities the plugins will work with (such as sessionId, stock, etc).
Data coming into the plugins should be abstracted as well. So you can have an IStockInfo interface in the host and each plugin should be constrained to provide their own implementation. The host can populate the common properties of these objects while the plugin takes care of the specific part.
What architecture and patterns can I use to share the most model and logic code between a WPF and an ASP.NET MVC application?
I am trying to achieve a bit more here than just separating my data entities from the two presentation projects. There is a lot more in common e.g. UI logic on what gets displayed under what conditions, when is something required, etc. that I would like to keep in the shared code.
ADDED: I am just beginning to really like the concept of view models independent of my entity model driving my presentation. While some of the annotations used in these are located in assemblies specific to MVC, none of the metadata provided is actually web specific. I would very much like to explore using my MVC view models as data sources for binding to WPF views. Any suggestions on this front will be most appreciated.
My personal favorite configuration is similar to the one Adam King suggested above but I like to keep the logic DLL as part of the web project. I run a project called CT Terminal that follows this pattern. My Terminal.Domain project contains all the application logic and simply returns a CommandResult object with properties that act as instructions to tell the UI project what to do. The UI is completely dumb and only processes what it's told to by the Domain project.
Now, following Adam King's approach I would then slap that Domain DLL into a WPF app and then code the UI to follow the instructions in my returned CommandResult object. However, I prefer a different approach. I wrote the MVC 3 UI to expose a JSON API. This API can be consumed by any application. The JSON API was simple because it was basically a wrapper around my Terminal.Domain project CommandResult object. The JSON returned would have the same basic properties. In this way I would write the WPF app to consume this API rather than the DLL. Now if I make minor changes to internal application logic I just deploy the Web project to the live server. All clients using the API automatically get this new logic.
Obviously if the changes being made affect the properties being returned from the API then that would require a release of new client code, but at least for internal logic you wouldn't have to do that.
One of the most widely used patterns seems to be having the Entities in a seperate DLL assembly, then having this referenced from each of the other projects.
MVC 3 suits the repository pattern very nicely, which can be a clean route to take in the first instance, and will work for both WPF and ASP.net
I actually found Rocky Lhotka's books, software, and videos on this topic very helpful. Here's a few links to his content:
http://www.lhotka.net/
http://channel9.msdn.com/Events/Speakers/Rockford-Lhotka
http://www.amazon.com/Expert-C-2008-Business-Objects/dp/1430210192/ref=sr_1_2?s=books&ie=UTF8&qid=1331834548&sr=1-2
Create a service layer for your application by specifying interfaces with methods that represent all of the operations you need to perform. Also, in this service layer, define all of the data types used by the application. Those data type classes should contain only properties, not operations. Put these interfaces and classes in an assembly all by itself. This assembly should be shared between your web app, WPF app, and the code that implements it.
Finally once you have this separation, you can freely develop the application's internal structure, and leave the responsibility of UI operations (e.g. what happens when you click xyz button) to the respective UI.
As an aside, you can expose your service layer, via WCF and web services. You can use this to make call from the web browser via javascript. You could do things like client-side validation or even look up values on the fly for drop down population. all while reusing it between your two application.
Starting with the obvious. Encapsulate your business logic and domain model in a separate assembly.
In terms of Presentation Layers and shared UI Behaviour, the closest you will get is the MVVM design paradigm, implementation will be C# in WPF/XAML and Javascript for your ASP.NET MVC web frontend.
For the web frontend you can get close to the WPF (MVVM) way of doing things with http://knockoutjs.com/ written by Steve Sanderson of Microsoft. Its MVVM for the browser. Also checkout http://www.asp.net/mvc/mvc4 for more info.
Use Web Api, let both the WPF and the Web application consume the services from Web Api.
Done.
Did you try using Portable class libraries. With this you can make the data layer and use it in ASP.Net MVC, WPF, Windows Phone, Silverlight.
I've written a program using Domain Driven Design in .NET 2.0 and I'm trying to implement a plugin framework for it.
I've implemented several types of plugins:
Domain Plugin
A domain aggregate composed of one or more domain classes
One or more View/Presenter pairs to display instances of the aggregate
An import/export service specific to the domain aggregate
A repository class
Service Plugins
Database Plugin (embedded or remote)
General import/export services (cvs, xml, competitor's data formats, etc)
As you can see, some plugins touch every layer of architecture. You could say that the domain plugins are miniature applications that simply depend on the main application to provide a framework in which to run. The ultimate goal is to let the user purchase and download only the plugins they need. I wrote them as static dependencies at first because I hadn't implemented a mechanism to load them dynamically. Now I'm trying to tackle the dynamic loading.
I'm trying to use an IoC container to manage the dependencies but I'm having difficulty working out how to find and load the plugins. In addition to the interfaces each plugin exposes to the main application, classes with each plugin also have their own interfaces they use to communicate with each other.
I'm using Castle Windsor as my IoC container and would like to take advantage of its autowiring capabilities both in the application and within each plugin as well.
How do I:
Find and load into Windsor implementations of a specific interface
Ensure Windsor resolves the correct one
If you think I'm going about this the wrong way feel free to say so. I still have time to change the design before my deadline.
I'm note sure I've understood you completly but consider looking at MEF (http://mef.codeplex.com/)
You could use something like the Managed Extensibility Framework to discover and enumerate your plugins at runtime. The plugins could then register the necessary types with your IoC container when they are discovered.
I just referenced my application domain layer dll to the new WCF service that I am creating.
On my initial tests I am able to use and return the objects from my domain layer on the WCF service.
Question that come in my mind is none of my domain claseses have [DataContract] attribute so does this create a limitation or problem for me that I should be aware of? Or any other concerns that I should know when using other class library in a WCF project?
You can either use DataContract or Serializable. If you use serializable you need to reference the dll with the types from both the server and the client. This is Ok when you have control of both, but can be a problem if other people want to access your service.
Take a look at this video for a better way of doing it than standard Visual Studio:
http://www.dnrtv.com/default.aspx?showNum=122
First law of distributed object design : don't distribute your objects.
But if you really want because you create a data oriented application, .NET Ria Services is what you want.