How to look at a .NET project architecture at a glance - c#

We are working on an enterprise level .net project, where-in we have a huge code base. We have our own different small frameworks implemented in the project.
While working, many a times it happens that I want to see a particular module's (or it's framework's) class hierarchy at a glance, which seems difficult. I have to drill down in different class files to see the relationships. Which is little difficult to do and takes time.
One way is that, I can create a dummy class.diagram file and drag drop particular class files to check the relationships. But it doesn't work that well.
Is there some other practice being used which I am not aware of ?

One thing I know of is Visual Studio 2013 Ultimate edition has Architecture tab (I know 2010 and 2012 also have it, but never used in them), that can be used to generate dependency graph of all projects in a particular solution. That can be used to generate dependencies within the projects.
I have seen it shows dependencies to the class levels.
You can take help of this Channel9 link to know more about it.

I've used .NET Reflector (with various plugins) in the same context.
There's a huge amount of plugins available at https://reflectoraddins.codeplex.com/ that ease the task even further.
On the "free" side, you'll probably want to give the following combo a try:
ILSpy (http://ilspy.net/) + AssemblyVisualizer (http://denismarkelov.github.io/AssemblyVisualizer/)
Note: all of the above is used to view the assembly's hierachy, not from a source point of view.

Related

How to maintain base code in separate Git repository?

Firstly, I'm new to VSTS and Git, so apologies if my terminology gets muddled!
PROBLEM
My situation is that I have a VS/C# Project (called "PluginBase") that is, essentially, "starting template" code for a plugin. Historically, I've would just copy that PluginBase project code every time I wanted to create a new "tailored/derived" build for a particular customer.
What I would like to be able to do is, as and when bug fixes are resolved and features are added to the PluginBase project, I'd like the option to migrate these changes to one or more of the "tailored/derived" builds. Likewise, if the bug was first found while developing a "tailored/derived" build, I'd like to migrate that back to the PluginBase plugin.
IDEAS
From my research, I've come across a few "possible" ways of achieving my goal, but I'm not sure which (if any) of these approaches are suitable.
Branches
Seems the common approach, perhaps the "best", but...
Means all code must be in the same repository? (otherwise can't "cherry pick" across) - which I'd prefer to avoid as this may not always be possible
Git Submodules
Seems more intended when projects are sharing a common "library" (not deriving from same code-base)
Also not sure Visual Studio fully supports this feature
Cherry Pick
Doesn't seem possible to do this from one repository to another?
Git Patch
Doesn't seem Visual Studio supports this feature yet?
So, if anyone has any advice, guidance or new suggestions for approaches I could (or should) be using, I'd really appreciate your input.
Many thanks! :)
Git Branches are definitely the way to go. The code indeed has to be in the same repository, git stores change sets and in order for a change set to be applied git has to know what happened since the code-paths split or it can not replace the correct lines of code.
Make a branch for each time you roll out a version to a customer, you can then cherry-pick across the different branches.

How to include 3rd party code in separate versions in one project

I've got an interesting problem on my hands and I can't quite figure out the right way of handling it. This is specific to sitecore, but I would imagine the fix to the issue would be one that could be applied to anyone that has multiple websites running different versions of a framework.
Right now I have 3 separate websites running Sitecore as the framework and CMS for the sites. One website it running code from Sitecore 6.5, another is on 7.0, and another is on 7.0 but will be 7.2 soon enough.
One of the core principles of programming is do not repeat yourself. I want to set up a separate C# project to include handling of Sitecore specific logic and classes. It would mostly include utility like classes that do simple functions to make my life easier checking many kinds of things. These base features are included in each version of Sitecore I am using.
Basically there is a ton of shared functionality between the Sitecore DLLs despite the differences, and I want to be able to write version agnostic code in one place.
I don't care if it needs to build out 3 separate DLLs for each set of Sitecore DLLs I need to compile with, as long as I can keep one base source. Is this sort of thing possible?
How I would handle it:
Setup an independent project and make use of configurations/symbols. A lot of the simple .NET code can probably be universally shared, however give you're working with different versions of SC you would most likely deal with deprecated functionality, API changes, etc. One example I can think of is UIFilterHelpers.ParseDatasourceString (which is deprecated in 7.2 in favor of SearchStringModel.ParseDatasourceString). There are a log of ways to approach this, but for example:
Inline Versions
#if SC7
IEnumerable<SearchStringModel> searchStringModel = UIFilterHelpers.ParseDatasourceString(Attributes["sc_datasource"]);
#else //SC72
IEnumerable<SearchStringModel> searchStringModel = SearchStringModel.ParseDatasourceString(Attributes["sc_datasource"]);
#endif
Another approach is to use partial classes and define version-specific implementations (then only include those in the correct project. Maybe you have:
Common.sln
Common.SC65.csproj
MyClass.cs [shared]
MyClass.SC65.cs
Common.SC7.csproj
MyClass.cs [shared]
MyClass.SC7.cs
Common.SC72.csproj
MyClass.cs [shared]
MyClass.SC72.cs
In the above, MyClass.cs resides in the root and is included in every project. However, the .SC#.cs files are only included in the project targeting the specific sitecore version.
This pattern is used a lot by libraries that target different .NET platforms or various configurations. To use an MVC example, you'd have MyProject.csproj, MyProject.MVC3.csproj, MyProject.MVC4.csproj, MyProject.MVC5.csproj (each with different references and possibly framework versions).

Managing Code Assets

I have written quite a bit of code of the past few years. I've been using the Visual Studio Development Environment for my C# code, but I wouldn't call myself an advanced user of Visual Studio. I can create projects, create source code, and build/debug the project. I don't use many of the advanced features of the IDE, so perhaps there is a simple way to do what I'd like.
My code is often reused - especially thing like filter tools, custom controls (plots/etc) and some communications code (COM/USB/etc). Every time I create a new project, I end up importing a lot of code that I'll need. This code is copied to the new project directory. If I end up editing that code in some way, I then need to update all of the other versions of that file in my others projects. I'm always having to verify that the code that I am importing is the 'latest and greatest'.
I know it is possible to add code to your project by link, and then you'll update the source file, but I'm curious if there is a better way. My example of a 'better way' is the Allegro Lisp compiler. When you start up Allegro, all of your code is loaded into Allegro, and is instantly available. Then you can start hacking around on anything you'd like, and have access to all of your previous code. When you edit something, and compile it, it is instantly usable in the rest of your projects as well. (Usually even if the program is open!) Perhaps this is something fairly unique to Allegro Lisp?
Are there any ways to do something like this in C#? I'd like to still be able to keep separate projects, but I'd like to share source between them and not have to worry about versions getting out of sync. What does everyone else do when they would like to recycle code?
Thanks,
Giawa
Take some time, work through the code and create different projects, for the likes of filters, plots. Give meaningful namespaces to these assemblies, put the code under source control, use external references to these repos in the source control of your main project, or only import the generated assemblies.
Copying code will lead to errors due to not correcting an error in one place, but correcting it another. Use source control, it's gold.

How to program three editions Light, Pro, Ultimate in one solution

I'd like to know how best to program three different editions of my C# ASP.NET 3.5 application in VS2008 Professional (which includes a web deployment project).
I have a Light, Pro and Ultimate edition (or version) of my application.
At the moment I've put all in one solution with three build versions in configuration manager and I use preprocessor directives all over the code (there are around 20 such constructs in some ten thousand lines of code, so it's overseeable):
#if light
//light code
#endif
#if pro
//pro code
#endif //etc...
I've read in stackoverflow for hours and thought to encounter how e.g. Microsoft does this with its different Windows editions, but did not find what I expected.
Somewhere there is a heavy discussion about if preprocessor directives are evil.
What I like with those #if-directives is:
the side-by-side code of differences,
so I will understand the code for the
different editions after six months
and the special benefit to NOT give
out compiled code of other versions
to the customer.
OK, long explication, repeated question:
What's the best way to go?
I'd be tempted to manage the differences during runtime with different licences, and enable/disable features using that configuration. Why ?
you only have to build one deployable.
you can unit test this much more easily, rather than build 3 versions and test this.
users can upgrade and simply be sent a new licence. They won't have to upgrade/reinstall.
You have to weigh this up against your concern for distributing a solution that your customers haven't actually paid for (and can simply enable via an appropriately secure licence key).
My first thought is to split your software into various modules (projects/assemblies), and then create three different setup projects in your solution, one for each version. In the setup, you only include the modules you need.
You will loose the "side-by-side" code, but IMHO this just creates complicated methods, instead of maintainable code. Use extension methods, if you want to provide more functionality for a type, or derive classes.
i would suggest to create the basic classes and features as normal, but to allow override for that mathods that would be edition-specific.
then you create a light/pro/ultimate edition assembly that overrides that methods.
then you need a factory, that instanciate the correct overriding types depending on the edition.
here you could work with the internal-accessor and make the code assembly internal visible to the edition-assemblys

Common C# source code for Windows and Windows Mobile

I have a goal to build an application with UI that would run on both Windows Mobile and "normal" desktop Windows. The priority is for it to "look good" under Windows Mobile, and for desktop Windows it is OK if it distorted. Before I invest days trying, I would like to hear if that is possible to begin with. There are several parts to this question:
Is .NET Compact Framework a subset of "normal" (please, edit) .NET Framework? If not, does MSDN have any information anywhere on classes that are in .NET Compact Framework, but not in "normal" (again, please, edit) framework?
Is behavior of shared classes same in both frameworks?
Is it possible to have a single Visual Studio 2005 solution / project for both platforms? If yes, how do to set it up?
Any other comments and advice? Any relevant links?
The CF contains a subset of the full framework (FFx), but it is not a pure subset. There are actually several things available in the CF that aren't in the FFx, which makes it a bit more difficult. CF apps also, except in the most rudimentary cases, use P/Invoke. Those calls are never the same from the desktop to the device, so they are not directly portable (though with a little abstraction you can have a platform-agnostic interface).
For the most part, behavior is the same. I've seen some cases where it's not, and I recall some event ordering not always being identical though, so trust but verify.
It's possible through very careful massaging of the configurations, but I certainly don't recommend it. It's difficult to maintain and very fragile. Instead have two project files, one for CF and one for FFx. You're likely to have code file differences anyway. Add the code files as links to each project so they both use the same physical source file. I'd recommend using some form of CI to help ensure they both build at all times.
Take a look at Dan Moth's MSDN article and blog entries on sharing code assets.
P.S. I found the poster online - it'll show you all the classes that are CF. I ordered it fro Microsoft because Kinkos wanted $65 to print it out in color for me! Microsoft sent me a couple of copies free - all I had to do was ask:
http://www.microsoft.com/downloads/details.aspx?familyid=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&displaylang=en
I have it hanging in my cubicle and it's a godsend when trying to remember which namespaces classes can be found in.
Nice multi-part question:
Differences between the Full Framework and the Compact Framework
The article above has links to relevant documentation about how class behavior differs (it definitely DOES differ in some situations)
Very simple! Create a single solution with a set of base functionality in a Class Library, then create two client projects (one for your desktop app and one for the windows mobile app). Finally, add references to the class library to both client projects.
Depending on the breadth of the project you are working on, you may want to check out the Model View Controller pattern. It may be a bit much for your project, but if you want to share UI behavior between projects, it can be a life saver.
Hope that helps!
CF, in general contains a subset of the classes from the regular framework - but you can't directly execute code from one on t'other. Additionally, rather than just being a subset, there are probably a few things in compact that aren't in the regular version, such as the GUI things specific for mobile devices (soft keys, etc) - assuming you are writing a winform exe, and not a web page (which might be the simplest way to get compatibility).
With some effort, it it possible to share logic code, in particular utility dlls - but they need different csproj files (since they have completely different compile-time "targets"). To reduce maintenance, you can often cheat by hacking the csproj to use wildcards, like from here:
<ItemGroup>
<Compile Include="..\protobuf-net\**\*.cs" />
</ItemGroup>
For UI, things get a lot tricker. In general the expectation would be to have shared business logic and separate UI for different target devices.
1). There is a Compact Framework so yes; And it is a subset of the full .NET framework. I've got a poster on my wall at the office that denotes a whole bunch of classes that work in CF... I don't recall off the top of my head if there are any that are purely CF, but I suppose there must be some. There are a couple of good books on the subject - one by Paul Yao that I have and another by Andy Wigley - both are available on Amazon.
2). As far as I'm aware, the classes that are CF and full framework work the same but need to be compiled for different targets.
3). I would hazard a guess that providing you only use classes that are common to both, that you could use the same solution, I don't know the extent you would have to go to make it compile for the compact device and the full version though, nor can I say with complete certainty that it can be done. I'd hazard a guess that the process isn't simple.
4). Go to your local book store and have a flick through those two books I mentioned. Like I said, I have the one by Paul Yao and it seems to cover most of what I could imagine needing on a compact device.

Categories