Referencing a C# web service project directly in C# solution - c#

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

Related

Not all namespaces coming across over WCF reference

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 :)

Can we add remove namespace reference (usings) dynamically in C#

I need to invoke WCF service 1 or WCF service 2, based on certain condition evaluated at runtime. Both the services are similar but hosted on different servers.
I have added two service references, NS1 and NS2 pointing to different urls. Current code already uses NS1. Considering this NS1 implementation has already been done at many places. What would be best way to refactor the code, to select dynamically which service has to be invoked ?
In general, it is considered a bad practice to program directly against the proxy generated by the svcutil.exe.
The best way is to wrap it in a class of your own and reference this class each time you require the service. This will also allow you to implement more advanced business logic such as routing (in your case) and other cross cutting concerns.
For example: you can now abstract from the application the strategy you are using to connect to the service, i.e. Service reference or ChannelFactory. You can easily share the service between different assemblies without ambiguity.
You are saying that you have much code written directly against NS1. Grind your teeth and wrap it. It is a lot of dirty work but the risk is very low.
Having said the above, I wonder about the requirement itself, where a service calls another instance of itself on another server (if I got you right). This smells funny, what is the problem you are trying to solve?

Software Design & Web Service Design

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.

Business library reuse or exposing services [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am having trouble deciding between two possible design choices. I have a web site which has a pretty extensive business layer and DAL (website, bll, and dal are all in multiple separate dlls). I need to design a windows service that can take some of my business objects, write them to a file, and store them locally within our network. The files are then imported into a 3rd party program which does further processing on them.
I can design this service one of two ways:
Wrap the service around the business layer and DAL. This would be quick and easy but the downside is every time the business layer changes, the service will have to be updated.
Add a web service to the web site and just query the web service for what I need. The windows service wouldn't have to use the business layer and as long as the web service doesn't change, I'll be good. The only downside is that I may have to create some basic business objects to parse the web service's xml into.
The windows service will have to poll the business layer/dal or web service every 10-20 minutes or so. The windows service is necessary because the web site is hosted offsite and thus doesn't have access to any of our local resources. I am leaning towards option 2 but I'm torn.
Given the two choices, which is the better option? Are there other possible options that I haven't considered? Also, how do you usually design for situations where you have one core set of libraries that are primarly used by a website but may end up being used either for data retrieval or to perform some function?
I'm not sure what the criteria is for storing certain business objects as files on the network, but if you're doing this on a regular basis then presumably you are trying to track changes of some kind, so there is another solution: Build the logic directly into the business/persistence layer.
If this secondary file storage is a business requirement, then it ought to be embedded directly in that tier and triggered by some sort of event. That way, instead of having an what is essentially an ad-hoc post-processing job that can get out of sync with the rest of the system, you have just one coherent system.
Invert the design - instead of wrapping a web service around the business services and using it for ad-hoc reporting, create a web service that encapsulates the data you need to receive from the export on a regular basis, and have your business tier send messages to it when new data is ready. You can send messages asynchronously so as not to tie up the business services, and depending on your reliability requirements you could set up a message queue (it's easier than it sounds, WCF already knows how to use MSMQ as the delivery mechanism, it's just a few configuration settings to change).
I can't say with any certainty that this is better than your first two options without knowing a good deal more about the architecture, the amount and type of data, the scheduling and reporting requirements, etc., but it is something you should consider. If you think that your business services are likely to change fairly frequently, then it might work better have it push data outward to a "warehouse" type abstraction rather than having a mining process to pull it.
Otherwise, I think I would go with option 2. I don't know if you've worked with WCF services before but you should know that you never actually have to parse XML. Everything is done through data contracts and when you generate a proxy for the web service, you get strongly-typed .NET objects. If you can pass your domain objects directly through the service API then it's really very little work at all to create the web service.
The real downside to a web service is that you have to take steps to ensure that your service contract never substantially changes (otherwise it can break clients). So you might eventually end up needing to create Data Transfer Objects on the service side to use as the public API instead of passing through domain objects. But in many cases you won't need to do this for a good long while, so go ahead and try it out, you'll see that it's pretty straightforward.
A variant of option two:
Add a WCF service to the site, exposing the information required as basic DTO DataContracts.
You could use AutoMapper or similar within the WCF service to handle the boring bit of converting your business objects to DTOs.
From your point two I understand, that you would just add the web-api for this extra-service. Thus, you would have to update two parts for any changes (extra-service, web-api, dll). With option one you would only have to update two parts (extra-service, dll), thus I would go with one.
BUT if you target for a general web api which you always have to maintain, go with option two.
For more flexibility instead of hard-wrapping your service around business and DAL, and instead of relying on the web site (through integrated web service) make use of design concepts like: interfaces, dynamic Type loading, Inversion of Control so your service is a thin decoupled layer that communicates with the business and DAL and allows for dynamic updates of the business and DAL without recompiling the service. Maybe put assemblies in the Global Assembly Cache of the machine to be shared across various other projects assemblies and apps.
I know it seems like throwing out jargon for the sake of it but that's how I would start to think.
Edit:
Loading types dynamically is actually amazing and easy. This is a quick C# pseudo code for one way, and without testing it might actually be right.
// Get a System.Type from string representation
Type t = Type.GetType("type name");
// Create instance of type.
object o = Activator.CreateInstance(t);
// Cast it to the interface (or actual Type) you're working with.
IMyInterface strongObject = (IMyInterface)o;
// ... and continue from there with the instance.
Instructions about how to formulate the string representation of a type name can be found in MSDN under Type.AssemblyQualifiedName, Type.GetType and similar places. In short you can see a lot of assembly qualified type names in the app.config or web.config files because they use the same format.

C# Web Service and using a variable

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.

Categories