I am dabbling in the world of web services and I've been making a simple web service which mimics mathematical operations. Firstly it was simple, passing in two integers and then a binary operator would be applied to these (plus, minus etc) depending on the method called.
Then I decided to make things a little more complex and started passing objects around, but then I discovered that a web service only exposes the data side of the class and not the functional side.
I was told that a good way to deal with this is to make the class on the service side a partial class (this side of the class encapsulating form) and on the client side have another partial class (where this side of the class encapsulates functionality). This seems like an elegant way of doing things..
So, I have set up two classes as described above, but it doesn't seem to be working as I was told.
Is what I am attempting possible? If so, where am I going wrong?
Partial classes are really a tool to separate auto-generated code from developer code.
A good example is the windows forms designer in VS, or the new DBML Linq DataContext generated code.
There's also an argument for using them with VSS style source control providers where only one user can edit a file at any one time.
It's not a good idea to use them for logical separation of functionality - the division only exists pre-compilation. As soon as you compile you get just the one class, but not one that it's easy to debug or track operations inside.
What you've described sounds like a really good situation for using WCF contracts. In that case both client and server would share an Interface (or Interfaces).
Your complex code would go there and could be unit tested separately - i.e. outside of your connected application. Then when bugs are found you can eliminate code issues quickly and move to investigating connection related ones instead.
Not with partial classes. A partial class is a syntax construct that gives you the ability to have different parts of the class in different source files. However, all parts of the partial class are ultimately compiled into the same binary.
You could use extension methods to add functionality to your class that represents the data contract.
You could also try implementing the class in a shared assembly and use the svcutil.exe /reference to get it imported in the client proxy instead of having a brand new declaration in the web service namespace.
As Franci said, it simply allows you to put separate parts of the same class into different files.
How you should structure things instead really depends on what you are doing. If I were you I would likely have a rather plain data carrying class and a consumer which could be used to process that data.
The use of a shared assembly is also a good idea. However, if you really wanted to be able to send the code from the server to the client CSharpCodeProvider would work.
(This thread's probably dead but...) I was thinking of doing something similar, but with the functionality on the (in my case) Windows Service.
Both the client program and the Windows service need access to the data, but only the service needs to actually do anything with the data; they are both including in a dll that holds a partial class containing contracted data members, however I get an error saying this partial class conflicts with the partial class on my service even though they are both in the same namespace and at the moment, the server's partial class is empty.
Related
I've been researching ways to build a Web Client using C# that is Single Page and is generated from XML files.
Essentially, I want to have a service that generates XML files that describe the UI of e.g. forms (not the problem). Those XML files are sent to the client, which in term reads the XML and dynamically creates the layout with all the controls. I had hoped to accomplish this in Blazor WebAssembly (I have also looked at ASP.NET WebForms, MVC and CORE (using DevExpress), but none of those are actually meant for SPA clients).
By comparison: We have an Android app that basically does this, similar to what is described right here: https://developer.ibm.com/tutorials/x-andddyntut/
But this time I am not developing an Android app in Java, this is supposed to be a WebClient. And as most coders in the company have a VB.NET background, my head of department would like for it to use C#. But I have tried finding ways to do something like this and have met lots of dead ends, as usually Blazor appears to be used with static pages from design time. I haven't managed to get it to run with RenderFragments, for example.
Any pointers with this would be very much appreciated!
Sincerely,
MR
You can generate the UI dynamycally using RenderTreeBuilder but most of its behavior is intended for internal use (take RenderTreeFrame for example) and therefore I don't think it is a good idea.
In short, I don't believe what you want to achieve is possible.
If these XMLs don't change often, I would think to create a transpiler that converts these XMLs to Blazor code and then recompile the app.
Not a direct answer to creating Forms dynamically, but a suggested alternative method.
For my application I have a number of services which have different properties but are based on underlying common base class. The services defined in several .NET Standard library for each type. The services are things like VoIP, Broadband, FTTC, Ethernet, Router Orders etc. etc. - not much in common, and very different types of data and behaviours.
The base service class has an abstract method called GetView which returns a C# type which is a Razor Component type. Remember in Blazor all those components are just C# classes. The type returned is a Razor Component in the same library (so we have UI as well as business and entity logic encapsulation).
The parent site loads a specific type of service, calls GetView and binds the service to the resulting Component.
That's pretty complicated to describe but I did a proof-of-concept application for this approach in the early days of Blazor as I realised it was going to be capable of this approach: https://github.com/conficient/BlazorDynamicList
There is also a demo site at https://blazordynamiclist.azurewebsites.net/
I won't explain it all in detail here but it follows a similar approach. There is an abstract base class ProductBase that has an abstract method GetViewComponent. Each product can return its preferred Razor Component to display itself.
The 'magic' is the DynamicComponent.cs which is a Razor Component with a BuildRenderTree method that creates a bound instance of the product's component view.
So for example I have this Web Api controller class AdministratorController and it contains a lot of tasks:
Create
Delete
Edit Password
Update
Get
Get all
Etc...
Now I have all these Tasks in 1 file AdministratorController.cs. But with all comments and annotations the file is pretty long.
Is it a good method to split this controller up into partial class pieces to make developers that search for a specific function get quicker to their destination? Or is this abusing the partial keyword
So for example I have a folder structure of:
--Controllers
⠀|-- Administrators
⠀⠀⠀⠀|-----AdministratorCreateController.cs
⠀⠀⠀⠀|-----AdministratorDeleteController.cs
⠀⠀⠀⠀|-----AdministratorEditPasswordController.cs
Obviously, this is a opinionated answer. Technically speaking, yes you can. It will compile.
I think you are right to split this into multiple files if it gets to long.
You could have partial classes. Or you could just have multiple classes. No one forces you to put all those methods into a single controller.
Personally, I'd opt for the multiple classes for practical reasons. You probably do dependency injection and you probably do it via constructor injection, because this is the default. With partial classes, which just means one big class but multiple files, you now need to edit your current file, plus the file that the constructor resides in to add a new service. It also means all the methods will need the DeleteDataService injected, although only the Delete method uses it. If you had one controller per method, you'd have the constructor in the same file and the other classes are not dependent on it.
But if for example you do injection via [FromService] attribute in your method then there is little difference between your two choices.
Structuring them in different files if keeping them in one file is too long is good. So good, that I don't think it would be too bad, even if you picked the "wrong" method to do it. So pick the one that seems most practical to you.
It depends on what you mean by "readable." To the extent that we must read a class, whatever we have to read doesn't become less by being placed in separate files. There's just as much to read either way. It could even be a nuisance looking through parts of a class across separate files looking for a particular member.
Partial classes might make us feel like we're separating code when we're really just making bigger classes. If we think we're making anything simpler with partial classes then they could even make our code harder to understand by encouraging us to add more to a single class while separating it into different files.
I'm not railing against partial classes. This stuff only exists if there is a use for it, and I don't mean to imply that anyone who uses them is abusing them. One example is autogenerated classes, like when we add a service reference (do we still do that?) We might make some modifications to the class, but then they get lost if we update the service reference and redo the auto-generation. If we put our custom code in a partial class then we can generate part while leaving the rest intact.
This is a follow-up to my previous question Stop my "Utility" from giving errors between different architectures, suppose I am trying to create a class library that looks something like this:
- Class Utility (Parent class)
... Utility functions and methods
(EG: Public Sub Sub1() )
- Class Utility_Web
... Functions and methods only related to Web / Web-Controls
(EG: Public Sub Web_Sub1() )
- Class Utility_WinForms
... Functions and methods only related to Winforms / WinForm-Controls
(EG: Public Sub WinForm_Sub1() )
Now, what I would like to be able to do is to just add the Utility dll as a reference to any of my projects and be able to access the functions and methods from ALL 3 of these classes by simply typing in, for example:
Utility.Sub1
Utility.WebSub1
Utility.WinFormSub1
In other words, not having to type:
Utility.Utility_Web.Websub1
And making it so that the end-programmer doesn't need to know the internal structure of this utility, they can reference all it's methods / functions with just the Utility. nomenclature.
How would I go about doing that? Is this where NameSpaces come into effect? Inheritance? Partial Classes? Modules rather than classes?
There doesn't seem to be any reason for these methods to be in separate classes if they are going to be accessed using the same class name.
If you want to split the code across many source files for organizational purposes, you can use partial classes.
This seems like an excellent instance where you'd want to use partial classes, all using the same Utility namespace. That would allow you to access the methods with Utility.WebSub1 and reduce a step.
A class named Utility is a bad class from the start. What is its utility? What does it help you do? How many other people are going to name classes Utility?
Name your classes for what they do, associate them in the namespaces where they make logical and functional sense.
Let's say that you are making a set of static methods that help out with a class that represents a Month. Why not put the methods into Month? If you're writing methods to transform data from one representation to another, name it that way (ie, MonthDataTranslation).
Don't worry about typing on the part of your clients or your client code. Intellisense and the C# using statement mitigate that a great deal and given the choice between a badly named, nebulous Utility class and a long, well-named class, I will pick the latter every single time.
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?
I've just begun learning WCF, and I'm coming from a total non-web background.
I have built a 3-tier desktop application, which compiles into one exe, which runs locally.
Now I want to move the whole business logics layer to a centric server, and make the GUI a client application.
As far as I understand, WCF should be my solution, as indeed, it helped me achieved what I wanted.
I mange to run remote functions, which is the basic of what I need.
My problem now, is that I don't quite understand the architecture.
For example, one of my services, returns a data type (class), from my Business Logics layer.
This class automatically becomes available to the client through the WCF mechanism.
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
For example a Save method (saves to the db).
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
What should I do? Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I know this is a basic question, but honestly i've searched a lot before asking here. My problem is I don't quite know what to search.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
Typically, if you want to encapsulate your business layer, you would not want to expose the business objects directly. This is because you now have a de-coupled client and you don't necessarily want to have to update the client every time the business logic/properties change.
This is where Data Transfer Objects (DTO) come into play nicely. Usually, you want to have control over your contract (data and methods) that you expose. Therefore, you would explicitly make other objects (DTOs) that make up the transfer layer. Then, you can safely change your client and server code independently (as long as both still fulfill the contract objects).
This usually requires a little more mapping (before you send or receive on each side) but it is often worth it.
For WCF, your interfaces and classes marked with [ServiceContract] and your classes marked with [DataContract] usually make up this transfer layer.
In WCF to expose method to client you have to mark it with OperationContractAttribute. So if you don't want clients to use your Save method, just don't mark them with with this attribute.
More info here: http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx
Pretty much same thing with properties, but different attribute: DataMemberAttribute. If you don't wont client to see it, just don't mark them with it (DataMember attribute)
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
Are you able to provide an example of your class and interface code? If so I'm sure you might be able to get more specific answers.
For example a Save method (saves to the db).
One possible approach would be to separate your class into 2 classes. Define the properties in the first class and then use that class as the base class of your second class. Then use the second class to define the methods. This would allow you to return only the properties while allowing you to keep your code DRY.
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
While you are able to define logic in the get and set methods for each property I would highly recommend revalidating any input received between services simply because any future changes or errors in one service could potentially lead to larger problems across your application. In addition this also helps to ensure your application is more secure against any potential attacks.
Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I agree with the above answers that you should be able to limit access to the different properties and methods using the data and method attributes within your interfaces.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
If you are looking for inexpensive but highly valuable video based training I've found the courses that Pluralsight offers to be quite good for both architecture as well as WFC services (btw, I am not associated with them, just enjoyed their training).