Take a look at following solution:
MySolution.sln
MyApp.csproj
MyClassLib.csproj
MyClass.cs
MyClassLib project referenced by MyApp project and contains MyClass.
MyClass is used only in MyApp, so it can be moved there.
Is there a way to determine such cases with some tool? Maybe Roslyn or Resharper inspections?
In case of complex solution with long history and many projects this is required feature.
No, there is no such tool for this.
Why? Easy: What if, sometime in the future, you create a MyApp2 and that also needs MyClass? Then it would be better if MyClass is not in the MyApp assembly.
Now you, as the human developing this, might know that there will never (although never say never) be a MyApp2 but a tool cannot possibly know this.
I have limited experience with ReSharper, but from my experience, ReSharper can not automatically detect these cases where a file can be moved, but can visualize these hierarchies.
Going back to your earlier example, the hierarchy tool would show that your MyClass.cs file is only used by a file in MyApp.csproj. (It would not explicitly say this, but you would be able to tell based on the hierarchy.)
You can either use CodeLens in visual studio to check where is used
or either right click on the class (or shift+f12) to "Find all references" and check where is used. This gives you a quick overview, give that you know your project structure, of the need of moving a class to some other place.
or use
Code analysis tools or other code tools to check redundancy etc.
You cannot determine those automatically unless you fiddle with these tools, as it's an edge case when yourself know wheter a class should be placed in some place or not and no AI can replace that, unless you write your own custom code analysis tool that does that particular task.
Edit: Since author seems so much driven and determined into digging into this problem, I suggest you to take a shot into T4 code generation, DSL, CodeDOM to check if you can actually generate or analyze the code you want
Or, create Custom code analysis rulesets or check if the ones already present suits for you
#MindSwipe is right. However, if you really need to do this then here's a hack:
ensure your solution is under version control. this can help later.
select project MyClassLib and run a find and replace in all files of the current project: public class with internal class.
build your solution to get a bunch of errors
open the ErrorList pane and sort it by Description
You should see error messages such as:
The type or namespace name 'MyClass' could not be found (are you missing a using directive or an assembly reference?).
If you see exactly 1 message per class then it means that class can be moved from the library project to the project that yielded this error. Otherwise it means it is shared by at least 2 projects; in this case you have to make it public again (undo the change made by the global replace for this class).
Related
Let's say I want to write a library and it should invoke OptionalLibClass.Run() if such method is available. However the assembly is big (like SkiaSharp) so I do not want to include it with my library, in case the end developer only need other features.
I know it's possible to use System.Reflection but you lose the benefit of Intellisense and static typing as well as getting a performance hit (though pretty minor IMO, usually it's not a problem).
Expectation:
Add OptionalLib as a reference. Still it should be optional: user should not have to install OptionalLib if they install MyLib from Nuget for example.
Write the following code in the library:
using OptionalLib; // .NET should be able to see this namespace
// ...
if (OptionalLibAvailable()) // How to implement OptionalLibAvailable?
{
OptionalLibClass.Run() // IntelliSense should be able to show me OptionalLibClass
}
End user (developer) doesn't need to do anything beside referring to OptionalLib if they want to.
Note that there may be multiple optional libs.
Possible Workaround:
While typing the questions, I thought of a few solutions though they are not as simple as I would like:
Make an interface IOptionalRun for example. However, end user has to provide their own implementation.
Following above workaround, add a separate MyLib (without OptionalLib) and MyLib.OptionalLib (with OptionalLib) that provides an IOptionalRun implementation. I think this is the best workaround so far and the closest to my expectation but we still need 2 separate assemblies and the user has to register the interface somehow. This workaround has a problem when there are multiple optional libraries and we want users to have any of their combinations (for example: do A if A is available, B if B is available but C if both A and B are available)
Using dynamic: the worst workaround IMO. Technically a shorter System.Reflection solution but still have all its problem.
EDIT: After reading my question again, turn out a solution will probably be the answer to: how to pack/create a Nuget package for a project that contains OptionalLib but it should not be in the dependency list (and don't pack that dll when packing the Nuget package). OptionalLibAvailable can just be a Reflection call to see if OptionalLib assembly is loaded in the current AppDomain.
Edit the properties of that big assembly reference, in the properties window, there is a property Private Assets, set its value to All, then repack your library, you will find that reference has gone from the .nuspec file.
I need to declare an attribute for coverage exclusion in my code, the issue is that i have a project group and i wish to create it somewhere where i can access it from all projects when i need it, right now i have it outside of the namespaces so it would be easier to use, and its declared in each project like:
public class CoverageExcludeAttribute : Attribute
{
}
is there any better way to achieve this goal in a way it could be access anywhere in my project group and declared only once, without having to add its namespace (e.g by using the global namespace) to each file i use the attribute in?
Thank you
While I actually agree with P.Brian.Mackey, I think the only way to do it is exactly as DjKraze said:
Create a new micro-project of type ClassLibrary, add a single .cs file with your Coverage(..) class and ensure that class is inside no namespaces block. Then build it and for each one of the other projects do a Add-Reference to that micro-project you just created.. That way it will surely work, and you will have a handy place to put any further 'common code' to be available everywhere.
However, each project will have to be updated with the reference. This is the minimum requirement - all in all, if you want to use anything instead of copying, it must be referred..
Sorry, almost no other options for such thing!
The other way is to .. ugh, copy. You can easily set up a simple pre-build script that will copy given .cs file to each one of your projects, but "adding" the file to the .csproj's build list is a bit harder, still possible with use of some Ruby or Python or friends...
Hm.. saying that, It may be possible to write a pre-build script to inject a reference to the micro-project automatically.. But I wont know if this is worth doing. Do you have more than 50-100 projects? Else, probably it's not worth..
This only applies to VS2010 and above
If you want some source code defined in each of your projects, but without a project reference, take a look at some of the functionality provided by NuGet, especially Source Code Transformations. These allow the addition of some source code to the project when you add the NuGet package to the project.
You can use Dependency Injection
http://en.wikipedia.org/wiki/Dependency_injection
The most popular are: Microsoft Unity, Ninject, NHibernate, StructureMap, Autofac.
Good luck!
If I'm dealing with one class and one public struct (not nested), Should I create a separate .cs just for the struct? Or leave it un-nested in its .cs file of the class? (This is assuming the struct relates to the class, but isn't so exclusive to the class that it should be nested and declared private)
Edit: I removed my initial question about two classes because I found C# classes in separate files?
Note that the only person(s) that can accurately answer this question is you, and your team. If your team is happy to find several related types inside a single file, combined due to ... whatever... then what I, or whomever other person, says, should be just ... irrelevant.
In any case, I would turn the question upside down:
Is there any reason to place two separate types (related by names, functionality, or whatever, but separate nonetheless) in the same file
and I've yet to come up with a good reason.
There are extensions/addins to Visual Studio where you can type in the name, and quickly navigate to the file, and I can think of three, but there are undoubtedly others:
DPack
ReSharper
CodeRush/Refactor! Pro
The first allows you to quickly navigate to a file by name. If you know the type, but have people putting multiple types into the same type, this will not be helpful, at all.
The second and third, lets you navigate to a type by name, but you shouldn't rely on people having those, or knowing how to use them.
To that end, I would advocate following these rules:
Project names should be identical to the root namespace of that project. I differ from this point myself where in some cases I name my projects "...Core", and I then remove "Core" from the namespace, but otherwise, leave the project name identical to the namespace
Use folders in the project to build namespace hierarchies
The name of a type should correspond 100% to the name of the file + whatever extension is right for your language. So "YourType" should be "YourType.cs", "YourType.vb" or "YourType.whatever" depending on language
That depends on who you ask.
I, personally, find it easier to read if they are all, always, broken out. However, the compiler doesn't care... so whatever you and your team agree is easier to understand.
In my opinion it's a good practice to avoid that. Some day a developer will be looking around for ClassBar in the project and won't be able to find it easily because it's nested in ClassFoo.cs
Tools like Resharper have a neat feature where you can just select a class, right click, place in new file to make this easier.
If you read any of the popular coding standards (Lance Hunt, iDesign, Framework Design Guidelines etc) most of them advocate 1 class per file.
Its annoying to scroll down and search for how many class each.cs file contains/hides.
Maintainability issue while using version control
Usability with our team.
Check here for more interesting discussion on same.
I think it was less about whether you can or whether you should. For things like this, I feel it's best to look to the convention in the rest of the codebase. Sometime conformity is better because it makes other developers jobs easier becaues everybody knows where things are.
If it's entirely new project and you are setting the standards here by yourself, do what makes sense to you. To me if the struct has no use outside the related class, I may put them in the same file. Otherwise, I seperate them out.
I am a Java developer, totally new to C#. I am currently writing a DLL for distribution across my organization. It is a very simple library containing a couple of classes and I do not see any real use in putting all of them into some namespace just for the sake of it. Do I really have to use a namespace? If so, why? Is it some kind of a best practice?
Do you need one? No. Should you have one? Yes. It'll help prevent clashes with identically named classes in other namespaces without having to resort to the (IMHO) ugly use of global::.
For throwaway test apps (e.g. checking Stack Overflow answers), I don't use a namespace. For anything else, I do. It's just an organization thing - if you're going to reuse code, it's helpful to separate it from other code you're also reusing in the same context. What I mean is, if you're creating an app using LibraryX and LibraryY, it's useful to be able to differentiate between them within the app. It's possible that they both use the same class names, for example - which will make the code ugly if you don't use namespaces.
Aside from anything else, if you're coding with Visual Studio it's actually more work not to include a namespace - you've got to modify the project to give it an empty default namespace.
There is no need to have a namespace. However developer studio expects you to be using a name space. For example, when you choose to add a class to a project developer studio will:
Create a file for the class
Add the file to the project
Create an empty class (in the above file) that is in the project’s default namespace.
A “project’s default namespace” is a developer studio concept not a C# concept and is set in the properties of the project.
As you are creating a dll for others to use, it will be a lot easier for the users of your dll if you have a name space:
People expect you to have a namespace (so may be confused if you don’t)
Namespaces make it a lot easier for your users if you have class (or enum etc) that is named the same as another class in any dll they are linking to.
Therefore I don’t see a good reason not to use a namespace.
My vote for "yes" i think it is good habit to use namespace. you can not be sure that people won't use same class names.
To respond to your comment about naming a class the same as it's namespace, read a little bit of the following article.
Short version: don't do that.
http://blogs.msdn.com/b/ericlippert/archive/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one.aspx
Basically System is a root namespace in asp.net C#.
In .net every programs is create with a default name space. This default namespace is called global name space. But program itself create any numbers of namespace, each of unique name.
learn more
http://asp-net-by-parijat.blogspot.in/2015/08/what-is-namespace-in-c-need-of.html
I create a number of add-ins for the Revit Structure API. Each tool has to habe a class which implements the interface IExternalCommand.
In the latest version of Revit, for your tool to work you need to have two attributes on the class that implements that interface:
[Regeneration(RegenerationOption.Manual)]
[Transaction(TransactionMode.Automatic)]
The values in brackets can change, but there must be something there. Often I am finding myself forgetting to put the attributes on, then when it comes to runtime it crashes. Is there any way in Visual Studio 2010 to add a compiler warning or error saying that if your class implements that interface it must have those 2 attributes? I have resharper if that helps.
Can anyone point me into the right direction?
Unfortunately not. (I don't know about Resharper, though)
If you have VS2010 Ultimate, you could write a custom Code Analysis rule.
Not during compile time, but I think it'd be easy to with reflection.
I suggest a separate program that uses reflection to examine your compiled assembly, finds all classes with the specified interface, then checks attributes on those classes, returning a nice friendly error message very quickly.
You'd still have to run this program after you compile your program, but depending on your IDE, you could set it as a post-build step.