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.
Related
I often come across the pattern that I have a main class and several smaller helper classes or structs.
I'd like to keep the names of thoses structs as clean as possible. So when I have a class that's called CarFinder that heavily makes use of some special Key object that is only (or mainly) used internally, I'd like to call that object Key instead of CarFinderKey.
Everything to remove all the extra fuzz that distracts me from when I try to understand the class while reading it.
Of course I don't want to pollute the rest of the code with a small helper class that is called Key - it most likely will clash and confuse.
In a perfect world I would have liked to have a keyword like internal to this namespace, but as that does not exist that leaves me the following options that I can think of:
Use internal and put the class in a different project.
Advantage: Perfect encapsulation.
Disadvantage: A lot of organisational overhead and unnecessary complicated dependencies.
Note: I'm not talking about really large self contained systems that undoubtedly deserve their own assembly.
Put it in a different child namespace, like CarFinding.Internal
Advantage: Easy to implement.
Disadvantage: Still can pollute when the namespace is accidently imported.
Put the helper class as a child class within CarFinder.
Advantage Doesn't pollute internally and can even be promoted as a public helper struct that is exposed to the outer world with CarFinder.Key
Disadvantage Have to put the helper class within the same file, or encapsulate it in an external file with public partial class around it. The first one makes a file unneccesary long, the second just feels really ugly.
Anyway call it CarFinderKey
Advantage Easy to implement.
Disadvantage Adds in my opinion too much fuzz to CarFinder. Still unncessary pollutes the naming, just with a name that is not likely to clash.
What is the recommended guideline?
Personally, I don't mind the extra "fuzz" caused by CarFinderKey, and here is why: Once worked on a very large project where we tried to use namespaces to disambiguate names.
So as you expand your system, you can very easily end up with 10 tabs open in your code editor, all named "Key.cs". That was seriously not fun.
It's opinion based. Anyway, I would:
try to make it a private nested class of CarFinder, which usually fails because the Key needs to be passed over to CarManager, you know what I mean. Public nested classes are discouraged.
I would put it into a sub-namespace called Core, a common name for internal stuff. For me, Core is "namespace internal" by naming convention.
The larger the project, the longer names you need. CarFinderKey is still a valid option.
I would never create additional assemblies just for this. It just doesn't feel right.
I had the same dilemma many times, and personally use (3) and a variation of (4).
(3): I have no problem with neither putting the nested class/struct within the same file (if it is small and really tied with the parent class), nor using a separate file within partial ParentClass declaration - the only drawback is that it gets one more level of indentation, but I can live with that. I also have no problem with violating FxCop rules or other recommendations - after all, they are just recommendations, not mandatory. But many people do have problems with all or some of these, so let move on.
(4): You already described the cons. What I'm going to share is how I do overcome them. Again, it's personal and one might or might not like it, but here it is.
First, let say we use a separate file for the key class and name the class CarFinderKey.
Then, inside the code file for the CarFinder class, we put the following line at the end of (or anywhere inside) the using section:
using Key = CarFinderKey;
This way, only inside the CarFinder class code file, anywhere CarFinderKey is needed, we can just refer to it simply as Key, what was the goal. At the same time we keep all the advantages and no clashes. Intellisence works w/o any problem. In VS2015, the lightbulb would even suggest to "simplify the name" for you anywhere it finds CarFinderKey inside that file.
Your decision should depend on your design. Is your Key class really a key only for CarFinders, or could it also be used to find motorcycles or houses or whatever.
One of the first rules the famous Gang of Four stipulated was "Design for change". If you really think that in the very near future your key could also be used to find houses or motorcycle, then it would not be a good idea to make your key class thus private that other could not use it.
Since you are speaking about private helper classes, I assume your key is only useful for CarFinders.
If that is the case and your design dictates that the Key is only useful for CarFinders, or maybe even: if it is designed such that it even isn't useful outside CarFinders the Key class ought to be part of the CarFinders class. Compare this to a simple integer that you would use in the CarFinders class, you would declare it private inside the CarFinders class wouldn't you?
Leaves you with the problem of one big file or a partial definition. From design point of view there is no difference. For the compiler there is also no difference. The only difference is for humans who have to read it. If you think that users of your class seldom have to read the definition of your key class, then it is better to define it in a separate file. However, if you regularly need to read the key class while reading the CarFinder class you should make access to the key class as easy as possible. If your development environment is fairly file oriented instead of class oriented, then I think that in that case the disadvantage of a large file is less than the disadvantage of having to switch between files.
I would put the class and their "helpers" in their own namespace MyNamespace.CarFinding,
so that you have :
MyNamespace.CarFinding.CarFinder
MyNamespace.CarFinding.Key
and I will just put this namespace in a sub-folder of the project.
This will not block the internal helper class to be used elsewhere in the project, but from the parent namespace you could reference your helper as CarFinding.Key
In Visual Studio, using a c# project, instead of placing a class that contains multiple methods and properties in a single file would there be any downsides to using multiple files with the partial keyword and nested file linking?
For example, if I have a class called Customer that has some properties and two methods: GetOrders and GetAddress. Instead of creating one file called Customer.cs and placing all the code for the properties and two methods in that file I would create a Customer.cs and place only the properties in that file. I would mark the class as partial. I would then create each method in a new file called Customer_GetOrders.cs and Customer_GetAddress.cs, each containing a Customer class marked as partial and only the code for that method. In Visual Studio I would nest the Customer_GetOrders.cs and Customer_GetAddress.cs files under the Customer.cs file.
The upsides I can see are less code in a file to look at so instead of scrolling up and down in a big file you would only see the code dealing with the method you are working on. Also if you are using source control merges would be easier since you would only have to deal with the code in each method. And since methods are bound by physical files you could easily see the change history of a method by looking at the change history of the file.
The downsides I can see are having a lot of small files but I don't think that would be so bad. Are there any other downsides with this line of thought?
Thanks,
Frank
The upsides I can see are less code in a file to look at so instead of scrolling up and down in a big file you would only see the code dealing with the method you are working on. Also if you are using source control merges would be easier since you would only have to deal with the code in each method. And since methods are bound by physical files you could easily see the change history of a method by looking at the change history of the file.
All of these upsides, in my opinion, are only "upsides" if the class is too big. If your class adheres to the Single Responsibility Principle, the file should never be "too big" to manage.
Also, most IDEs (such as Visual Studio) already provide a huge amount of functionality to navigate the files quickly (such as the pulldowns that jump directly to members).
The downsides I can see are having a lot of small files but I don't think that would be so bad. Are there any other downsides with this line of thought?
You're splitting your types up across multiple files, which makes it far less maintainable and more difficult to follow, as the data used by the type is no longer near the methods that use it.
You also add extra maintenance cost to refactoring, as method renames, for example, now would require additional work (file renames) which would break your "history" of that method within that file.
Overall, I'd find this a bad practice. Partial classes are great if you have generated code, and want to be able to add other logic to a generated code file, but otherwise, they tend to be something I'd personally avoid.
It is a Code Smell to me: a class sufficiently large that something is gained in understanding by partitioning into multiple parts is an indication that it has too many responsibilities. It's probably a poorly thought out abstraction that should be partitioned into multiple classes.
For example, if I have a class called Customer that has some properties and two methods: GetOrders and GetAddress. Instead of creating one file called Customer.cs and placing all the code for the properties and two methods in that file I would create a Customer.cs and place only the properties in that file. I would mark the class as partial. I would then create each method in a new file called Customer_GetOrders.cs and Customer_GetAddress.cs, each containing a Customer class marked as partial and only the code for that method. In Visual Studio I would nest the Customer_GetOrders.cs and Customer_GetAddress.cs files under the Customer.cs file.
From a modelling perspective, GetAddress() and GetOrders() shouldn't be methods, at least, not on the Customer object. A Customer probably has 1 or more Address properties and single, collection-like property, Orders, that represents the customer's order history.
I think your abstraction is missing some classes. Perhaps you need an OrderFactory, that given a Customer (and possibly other criteria), knows how to find 1 or more of the customer's orders.
There is actually a big problem with visual studio. The more files that you have the longer it takes to compile and even load a solution. Give it a go sometime with lots of text files, imagine 7 or 8 extra files per class a standard solution would explode in size in no time and .
From a .net compiler perspective there is nothing wrong with this.
The only other problem is maintainability ie code navigation knowing what goes where.
Recently I was considering a class that seems to become fat because of too many methods in it.
A legacy code...
That has many business logic-wise methods doing all types of CRUD on various 'Etntities'.
I was thinking
make this class partial
and then grouping all methods by their target entities they work on
and splitting them into separate physical files that will be part of the partial class
Question:
Can you list pros and cons of such a refactoring, that is making a fat concrete class a partial class and splitting it into slimmer partial classes?
One pro I can think of is the reduction of conflicts/merges in your source control. You'll reduce the number of parallel check-outs and the merging headaches that invariably come when the devs check-in their work. A big pro, I think, if you have a number of devs working on the same class quite often.
I think that you are talking only about simplicity to handle the class. Performance or behaving pros and cons shouldn't be because when compiled it should generate the same result:
It is possible to split the definition of a class or a struct, or an interface over two or more source files. Each source file contains a section of the class definition, and all parts are combined when the application is compiled.
Now answering pros and cons I can think in (only about simplicity):
Pro: less conflicts / merges if working in a team.
Pro: easier to search code in the class.
Con: You need to know which files handles each code or it can get a little annoying.
I would go for the refactor. Specially considering all facilities given by the IDE where you just have to click F12 (or any other key) to go to a method, instead of opening the file.
Splitting a large class into partial classes perhaps makes life easier in the short term, but it's not really an appropriate solution to the code bloat that your class is experiencing.
From my experience, the only benefit that splitting an existing large class up gives you is that it's easier to avoid having to constantly merge code when working with other developers on said class. However, you still have the core problem of unrelated functionality being packaged into one class.
It's better to treat the breaking down to partial classes as the the very first step in a full refactoring. If you're able to easily extract related methods and members into their own partial classes (without breaking things) then you can use this as the basis for creating entirely standalone classes and rethinking the relationship between them.
Edit: I should clarify that this advice is given under the assumption that your legacy code has unrelated functionality in one class as a result of years of "just add one more method here". There are genuine reasons for having functionality spread across partial classes, for example, I've worked on code before that has a very large interface in one file, but then has all the methods grouped into partial classes based on areas of product functionality - which I think is fine.
I would say Partial class would help to maintain the code and will be more helpful when we have legacy code to avoid more changes on the reference side. Later will help to refactor easily
If you're concerned about how to refactor a class, I suggest reading into SOLID design principles.
I think you should focus on Single responsibility principle (the S in SOLID), which states an object should only have one responsibility.
I think my answer is not directly answering your question whether using partial classes would be beneficial to you, but I believe if you focus on the SOLID design principles that should at least give you some ideas on how to organize your code.
I see partial classes only as a way of extended a class that's code was generated (and can be re-generated at any time) that you would like to extend without your custom code being overwritten. You see this with the Form generated code and Entity Framework DbContext generated code for example.
Refactoring a large legacy class should probably be done by grouping and separating out single responsibilities into separate classes.
Is it good practise to have multiple class definitions in one file? or is it preferable to have one class per file?
I prefer one class per file. You'll never have to search for the correct filename because it is always the class name.
One class per file.
That way you can avoid having to merge edits when two people have to edit the same file because one is working on class A and the other is working on class B. While this should be automatic in any source control system, it's an extra step that can be missed which would cause problems.
Far better to have a process that didn't allow this sort of error to occur in the first place.
I do not see any issue with multiple classes in the same file, as long as the classes are related to each other.
If you have resharper, you can always use the navigation tools to find any class.
It is generally best practice to have one file per class.
Some folk, not me, like to have more than more one if they are related and very very small in size. Others might do this in a prototyping stage. I say start and stay with one per file as does Scott McConnell in his discourse on Class Quality in his seminal book Code Complete
To quote, "Put one class in one file. A file isn't just a bucket that holds some code. If your language allows it, a file should hold a collection of routines that supports one and only one purpose. A file reinforces the idea that a collection of routines are in the same class."
I think it's preferable to have one class per file and to organize them in folders having the same hierarchy as their namespaces.
Most programmers would consider one class per file to be a best practice.
Usually - no.
Following practice "one class per file" simplifies browsing of solution.
Additionally if you have a big team of developers and source control tool that uses pessimistic approach (exclusive locks) - your developers will have hard time while working on the same file.
I guess it is down to preference as you said.
I think you'll find most online examples/ most code is one class per file for easy management.
I sometimes put 2 classes in a file - only if i'm using the second class as an entity and it's only being used in the first class.
I guess you ask because you've noticed already that it's considered best practice. Given the obvious benefits (and some less obvious ones mentioned here), why would you want to do it differently? Are there any benefits at all in multiple classes per file? I can't think of any.
Usually it is the best solution to have one class per file (with the file named exactly like the contained class).
I only differ from that if
There are lots of small enumerations ->I collect these into a single file e.g. Enums.cs
There are lots (20+) of generated classes/interfaces that directly relate to each other ->Into one file E.g. Interfaces.cs
There is stuff that is no direct functional part of the application and in close semantic consistance (e.g. everything you need for interop. Thats usually a few structures, enums, constants and a single class) -> That goes into a single file named after the interop class.
Private inner classes -> Stay with their parent class instead of partial classes
I would say no, i know devexpress hates it aswell ( It has some detection bad practives).
But i do have it sometimes, when its a very small class thats basicly only used by the "main" class in the file. Personaly i think it comes down a bit to taste, there is a balance between having 10k lines long .cs files or having to many .cs in your project.
I think in terms of it being a "best practise" approach then probably yes. However, really it depends on the project. I tend to group related code into separate units for example:
MyApplication.Interfaces
MyApplication.Utils
MyApplication.Controllers
I really think a class only ever deserves it's own unit if it becomes huge. However, if it does get to this stage, you should start to consider moving some code into helper classes to separate the logic.
I would have to agree with most on this. One class per file is ideal. It makes it easier to see what's available in a project without having to rely on intellisense to discover types that are available in a given assembly.
I think the only time I ever fudge on the one class per file rule is when I'm defining a custom EventArgs class and it's related to an event that's fired from another class. Then typically I would define those in along with a delegate for the event in the same file. I don't know that it's a good practice one way or another or just out of sheer lazyness??
If you work on a very large project, too many files can slow down your build times significantly (at least with C++). I don't think that rigid adherence to a rule is necessarily the way to go.
One Class Per File is my Preferred approach, it helps me get rid of any confusion later on... I tend to use a lot of partial classes though...
As long as I dont break the 1000 line barrier, I'll stuff in as many related classes that makes sense.
Sometimes an abstraction may only be one overridden method.
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.