Does ASP.Net MVC4 Cache References? - c#

I ran into an issue today that is making me pull my hair out.
I've created a WCF service which is fairly simple as it only exposes two operations and no data contracts. This WCF service sits on top of a business logic layer. Inside this business logic layer is a dll which exposes some contracts (just plain interfaces).
I've also created two test clients for the service. One is a console client and the other is a MVC4 application. Both reference the same endpoints and they both reference, through a project reference, the contract dll.
Now, all is fine until I change the contract by adding or removing a method, or even changing the signature of an existing method. At that point my MVC4 app blows and throws all over the place. Keep in mind that I'm not changing the WCF contract, just some internal contracts.
The reason is that inside of the business logic layer I am initializing my AutoMapper profiles via a static constructor. Inside this static constructor I basically get all the assemblies of the current domain and iterate through them looking for objects that implement IProfile. It's when I start trying to get types out of one of the dlls that reference the contracts dll that I get a fatal exception: System.TypeLoadException.
Now, the console client behaves just fine. Again, referencing the same dll's through a project reference. I can change that contracts dll all day long and it's just happy as a lark, but MVC4 blows chunks. If I go back and make the interface exactly like it was before MVC4 is happy.
I noticed that the path to the assembly that was failing to load is in the Temporary ASP.Net files location. I blasted that entire directory and still no luck.
I can supply code, but it might be better if I gave you a dependency graph. There's already about 5k lines of code in the BLL.
Thanks in advance.

Related

Is it possible to add a WCF Web service reference to the .NET Application in IIS production environment

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.

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

Namespaces and type resolution in C# solutions with webservices

This might get a little convoluted so please let me know if you need clarification.
I have a solution which contains the following projects
Project A - WPF application
Project B - ASP.NET application (with exposed webservices)
Project C - Class Library
Both project A and project B reference types that are located in project C, but more importantly project A makes webservice calls to project B using types located in project C.
The problem I am running into is it appears that when making webservice calls I have no way of referencing the types located in project C directly but rather need to use the types as exposed by the webservice.
Now the basic idea of why this is done I understand (obviously typically the consumer of your webservice would only have the WSDL to go from) however in my case this is an internal application (which is part of a single solution) so this is not a concern.
The biggest problem I see with continuing this approach is that any updates to the types in project C will need to be reflected in project B and then "refreshed" in project A. This seems pretty nasty to me. Surely there is a smoother path?
Am I wrong? What is a typical approach to this issue?
You may be a little confused here.
The types in Project C and the types you see when you add a reference to your web service are different.
When you added the Web Service reference. Visual Studio used svcutil.exe, read metadata from your web service (I'm assuming .asmx?) and then created proxy classes for you.
Check the types for the Web Service (they will obviously have the same names). Put your cursor on them and pres F12. It'll take you to some designer generated code.
So there is no real workaround as such. When you update your types in Project C and then Update your web services in Project B . You will have to Update Service Reference from Project A Which again uses svcutil.exe and regenerates all your proxies.
Also, this is the same way WCF Services work too.
#giddy is correct - the types exposed by the web service are different to the types contained in Project C - even though their definition may be identical. The web service exposes type information via a wsdl, which Visual Studio uses to generate proxy types.
There is a way around this - you can create an interface which declares all the methods in the web service class, and include it in your shared library. You can then skip the "Add service reference" process, and create the web service proxy with code (you will not need the proxy classes, as you use the classes in the shared library).
Either way, if you make a change to your data transfer objects or the web service class, you will need to update the client by either by requerying the wsdl using "refresh service reference", or by copying the shared library over.

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.

How do I refactor data contracts in WCF services?

We have lots of WCF services that are only used by our own code; the code that uses them is mostly in the same solutions files that contains the services.
However they do not use a shared assembly for the contracts, so each time a data contract is change the reference to the service has to be updated by hand in all projects that use the service. (Then the code needs to be fixed up by hand)
So how do I do a simple refactoring like renamed a data item in a data contract?
Is there a way to update all references to services in a single solution with one command, rather then having to click on each reference in each project?
You may have already answered you own question here.
Move your data contracts to a shared "Contracts" project, which will allow you to use the built in Refactor -> Rename option in Visual Studio to change the name, with the change being reflected in all of the projects in the solution.
Update
To clarify, the Contracts project is an internal "organisation" of your contracts. It allows many of your projects to reference one set of contracts. For example...
WCF service exposes "List GetCustomerById(int id)".
WCF service may call down to a processing layer, which might need to calculate something using another project etc. All of thes projects can use the single "Customer" definition from your Contracts project.
Any consumer of the WCF service would get the definition of the Customer via the service reference. You wouldn't share your Contracts project or send the dll for their use.
With your current settings you can't do it because you are regenerating the proxy each time. This is good from SOA perspective as data contract should not change very often. But if you are controlling both client and service and it is all .Net you can do as Shonee suggested. Use the /r option in svcutil to generate the proxy from the common assembly. Then you can refactor easily.

Categories