I need to create a project for multiple web services using WCF in c#. The web services will be calling other assemblies to perform the core processing. The assemblies will be accessing data from SQL Server. One of the parameters that will be part of every web service method will include the database to use. My problem is how to pass the database parameter to assemblies to use. I can't change all the signatures for all the satellite assemblies to use. I want to reference some kind of variable that the satellite assembles reference. Theses same satellite assemblies are used with a Windows Forms app and an ASP.NET app so I would need to have something that all types of applications could use. Static fields are not good since for one web service call the database could be "X" and for another it would be "Y". Any ideas?
This is the sort of thing that might play nicely with an IoC or DI framework - having some interface that includes the database information, and have it pushed into all the callers for you. Even without IoC, hiding the implementation in an interface sounds like a solid plan.
With your static concept; a [ThreadStatic] might work but is a little hacky (and you need to be religious about cleaning the data between callers), or another option is to squirrel some information away on the Principal, as this is relatively easily configured from both WCF (per-call) and winforms (typically per-process). In either case, be careful about any thread-switching (async, etc). In particular, note that ASP.NET can change threads in the middle of a single page pipeline.
Related
We have an ERP Application developed in .NET 3.5.
Recently I've developed a WCF Service to expose data retrieved from our business client's DB server.
Now I've added a service reference in my local consumer project and tested.
To put this application in production environment, we have to compile DLL every time and then publish in live.
I like to avoid the whole DLL compilation process where I have to depend on my developers team to acquire code and compile. (This issue is because of not using a TFS or VSS to work on single solution file)
So I'd like to know whether one can add a service reference & class file to the project which is in production environment at IIS root directory without recompilation of the consumer assembly.
It's difficult to know what it is you are wanting to avoid here, but it sppears you'd like to be able to add code to an existing application without rebuilding/redeploying that application. This is called hot-swapping.
However, service references are code. Therefore they need to be compiled, along with the consuming code, into one or more assemblies. This is the nature of consuming web services using a service reference.
You could use reflection to load code at runtime which would allow hot-swapping of an old with a new dll, but the new service reference would still need to be compiled into the new DLL.
A better way of approaching this would be to not use service references at all, but call the service directly using ChannelFactory. This allows you to call a service without using the service metadata to generate a service reference.
Now, WCF respects something called Data Contract Equivalence, which roughly translated means that a service will respect a passed type providing the type passed looks the same as a type exposed as an argument by the service.
What this means is that your development team can, based on the types defined in the service, create their own equivalent types, and then call the service passing (or receiving) these types as if they were native service types.
However, this does not remove the requirement that all this will need to be compiled at some point. What it does do is remove the coupling between consumer and service.
Can you provide clarity on which scenarios does hot swapping /
ChannelFactory are beneficial to use
While this won't directly address your requirement,
Hot-swapping is useful for changing the behavior applications at run time. This is important if:
your application is a black box,
you need 100% availability, or
your deployment process is so arduous that the cost of deploying new versions is prohibitive.
ChannelFactory is beneficial in many ways, but basically it removes the requirement to generate service references, which, while ultimately deterministic, can be unpredictable and generally increase complexity.
ChannelFactory also enables you to then take advantage of data contract equivalence, which further decouples the consumer from the service. If, for example, the service contract changes to add a new field to a type, then the consumer can generally continue calling the service without change.
I am trying to improve the speed of a C# job, let's call it 'WidgetProcessor'. In one run, WidgetProcessor will process about 5,000 widgets and take about 12 hours to complete (about 8 seconds/widget).
WidgetProcessor makes references to 3 different web services and calls them multiple times for each widget processed. There are various performance/design improvements that can be made to the 'WidgetProcessor' program, but I want to test if the multiple web service calls over the network cause the job to run slow.
I have the source code for each of the three web services (and have access to all of the resources those web services use), and I'm wondering if there is a way to easily use the web service interfaces in WidgetProcessor by referencing the web service projects themselves (instead of calling the web service over the network). The web services are implemented in C#.
I would reference the service implementation classes directly, but the main problem I'm running into is that the web services have collectively about 100 data contracts and the public facing names are different than the implementation classes.
[DataContract(Name = "WidgetInfo")]
public class WidgetDataContract
{
// DataMembers
}
Thus, referencing implementations directly means I'd be making many code changes in WidgetProcessor. Rather, I'd like to use the service interfaces, so that code changes can stay at a minimum.
Basically, I want a service in my WidgetProcessor solution that looks and acts like a web service, but doesn't perform its operations over the network.
Is this even possible?
You can add adapter classes which subclass the implementation with the name specified in the datacontract:
public class WidgetInfo : WidgetDataContract { }
If you are finding the overhead of the service call to be overly expensive, you may see benefit of going to a different binding or serialization format. WCF can approach in-process speed when tuned properly.
Edit: If you are intent on not modifying any code, you do have a couple options, but I think they are solutions in search of a problem:
Mono.Cecil or Roslyn to automatically map between the classes pre- or post-build
For only the types, you could use TypeForwardedToAttribute, but property access is problematic. This may be dependent upon placing the svcutil generated classes in another assembly.
Use Castle to build dynamic proxies and map access based off of attributes
I have 3 projects in my solution.
A common class library named ReportBuilderLib
A WPF application named ReportClient that contains a service reference to a 3rd project -
A WCF web service which contains web methods for my application to call upon.
Initially when setting up both the service and the application i added the common library to references on both projects so that i could use the classes i needed to in both.
It quickly cam clear that in the process of generating the code to use the web methods in my client application, it was automatically importing certain namespaces that i had used in service application.
This was throwing me conflicting reference warnings as they were effectively being imported from two separate resources.
I then removed the reference to the library in my report client, i could see that VS was only importing one out of the two namespaces my client requires. Both of which are returned by methods in my ServiceContract!
Having looked at the generated code for the client, it seems to be re-creating the classes i have included in the library and providing only the public properties for access.
Is it possible to use librarys like i am trying to with WCF. Or should i scrap the common library idea and simply create some data transfer classes on the service end?
You should be able to reference the common library on both ends, but it may be useful and less of a headache to implement data transfer classes like you suggested. Using special classes (or serialization like JSON) to send and receive data from the service would make it easier for you to re-use the service for multiple client projects.
Any time you decrease the coupling between layers of an application you make it easier to implement changes/upgrades in the future :)
I'm about to design my Web service API, most of the functions of my API is basically very simular to my web application.
Now the question is, should I create 1 single method and reuse them for both the web application and the web service api? (This seems to be the logical solution, however its very complicated; it's much easier to duplicate the method used by the web application, and keep both separate, ie one method for the web application and one method for the web service.)
How do you guys do it?
1) REUSE: one main method and reuse them for both web application and web service application (I like this but it's complicated)
WebAppMethodX --uses-->
COMMONFUNCTIONMETHOD_X
APIMethodX ---uses---->
COMMONFUNCTIONMETHOD_X
ie Commonfunctionmethod_x contains reusable set of common features
PRO: less code, less maintenance, less bugs.
CON: very complicated
2) DUPLICATE: two methods, one method for the web application and one method for the web service.
WebAppMethodX
APIMethodX
PRO: simple
CON: duplication = more code, more maintenance, more bugs!
Your use case will very likely be different for your public webservice API than for your internal application API. Create a common service project / tier and use that same tier from both your web app and your public-facing webservice API. Create a separate http-invokable method for each of your web app and your webservice.
It comes down to there being
1) different security concerns. For instance, it is nice (often required) to provide a sample client application making use of your public API so that others can easily get up to speed with what you've provided. That client API may need to pass object constructs that you provide them that have been stripped of internal, secure logic/content. (Remember that compiled C# might as well be clear text with Reflector!)
2) different needs and constraints. For instance, for an internal application call you're going to sometimes enforce different business rules vs. your public facing webservice API (often with the latter being much more constrained to scope).
If you design your business logic into your service layer and invoke those classes/methods well from your web project and your webservice project respectively you're going to have a lot of code reuse anyway without trying to overcomplicate things by mixing use cases.
One method. Otherwise when you find a bug and fix it in one, then forget to in the other... you will cry.
One method, in the web service, and have your web application call it.
I don't understand what "one main method" for both means. Web applications don't have a main method; they're deployed to an app server.
One other point to note: you should write your service in terms of a POCO interface. Once you do that, deployment becomes a choice you make.
It depends..
Normally, I would separate them. This way you remove interdependency between two high level processes. code reuse is good within a process but sometimes you want to be able to use a different app on the same service.
If the two are highly dependant on each other, however, you will want to reuse the same functions so that changing it in one place will change it in another. Thus avoiding more potential issues with the development process.
I'm writing a tool in C#.Net that will be used to generate Catalogs of content which users can browse. Initially I am creating a WinForms based interface, but in the future I'd like to be able to create a web based interface as well. So I've been careful to generalize the interface to a Catalog so that it does not depend on a specific UI.
My only experience with web development has been creating my own HTML website back in the early 90's, and I've done a little ASP (not ASP.NET). Now with ASP.NET it seems that I should be able to leverage my existing C#.Net object model, to create a web base interface. But I really hasn't done anything with ASP.NET beyond a simple hello world example.
Are there any special considerations I should make in designing my object model so that later I can create a web interface to it?
Here are few things to follow:
You should package your object model
is separate project (that you need
to do anyway to share it among
different projects) and make sure
that you do not add specific
references to it (for example, don't
add System.Web, WinForms, WPF etc) -
this will automatically avoid any
unwanted dependencies.
Try to have your classes as lean as possible. Avoid classes that track change states etc - in web scenario, tracking state over multiple requests is expensive. So it's best to have to your objects carry data only.
Consider the possibility that your objects may need to be serialized and/or passed over a wire. For example, a middle ware services serving both windows & web client. Or web page storing the object in the view-state.
There really shouldn't be that big a difference.
Be careful about placing too much “intelligence” in your entity classes. That’s a pattern I’ve seen often in Windows apps. Don't make references to controls that are specific to Windows Forms development in the parts of your project that you want to reuse for the web application.
Repository patterns work well with both Windows and Web applications, because you often want to optimize the web apps differently for performance with multiple users.
Your requirement can be handled with a multi-tier architecture:
http://en.wikipedia.org/wiki/Multitier_architecture