Cross-reference code and business requirements - c#

I was curious if a tool exists to collect Metadata references in code to somehow link business requirements with sections of code?
I'm currently working on a legacy system that does not do anything like this, so I'm envisioning a Visual Studio extension that allows me to define Metadata tags. Once they are defined, I can add them to sections of code such that they are searchable.
So, for example, if I am working on the billing subsystem, perhaps I add the [Billing] tag so the next developer knows the specific part of the code that I used as an entry point into the code.
Is this a thing? Or could this even be leveraged to be useful? I just find that I am often lost for months learning a new system and always wished there was a way to search the code for business requirements. Or at least had a dictionary of search terms.

I think a problem is that business requirements may not map directly to any kind of module, but may be spread over the code-base. So where would you put your tags?
Requirements may also change, so you might have tags linking to requirements that may no longer accurately describe the current behavior.
I would propose to instead document such requirements thru tests. Preferably automated tests whenever possible, but in some cases manual tests might be appropriate. This should let you know whenever a requirement are no longer fulfilled, and that lets you either change the test, or the product. Such test can also be useful if you are new to the code base to gain some understanding of how the code is intended to work.
Having a good architecture, appropriate code comments, and some kind of project architecture documentation are other common tools to make familiarization easier, but it is fairly rare that all of these things exist and are up to date.
Linking source code to external systems can be somewhat risky, since code tend to outlive systems and people. I have worked with code bases that have gone thru at least 4 different source control systems, and three different issue trackers. And even if you think having such tags is the best thing since sliced bread, you successor might consider it unnecessary bloat.

Related

Testing legacy ASP.NET Web Form [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need help figuring out how to test old legacy asp.net web forms.
A lot of web pages in our project are written long time ago and now it is getting to a point where maintaining/adding extra features are a pain in the neck. There are no methods whatsoever. The codes are not modularized and server side code are all over the place at the front pages (.aspx) mixing together with the UI logic.
Rewriting these legacy asp.net web forms seems to be the only way to go for long-term benefits. However, here is our problem. These pages all work fine right now, but no one on our team completely understands the business logic behind them and reading through the code line by line will be very painful. We thought maybe writing some test cases and apply that same test on our newly re-factored, modern web forms and compare the results will be more promising and accurate.
Does anyone know how i can go about this? How to test legacy asp.net web forms if the codes are not organized and madularized? Any suggestion or recommendation will be helpful.
So far i have looked at Selenium but seems like this is more for UI testing than for business logic. My main focus will be what data gets pulled from the database and displayed on the form and what data gets written into database (especially which tables) after the submit.
Also looked at Visual Studio built in Test suite, but seems like this approach requires the code to be organized in methods and functions so I didn't continue my reading.
Another thought i have in mind is monitoring the database and see which tables get changed during the period when i manually open a web page and input/submit some data. Will this be a good option?
Any thought will be appreciated. Thanks!
These pages all work fine right now, but no one on our team completely understands the business logic behind them and reading through the code line by line will be very painful.
Ok, so this is really the crux of your problem. Do you have access to the stakeholders of this application (i.e whoever it was designed for?) They are probably the best people to explain to you how its supposed to work. You need to get access to these folks and have them give you at least a crash-course in the "domain" of the application.
Only when you and your colleagues fully understand how this system works can you test it. If you don't have access to the stakeholders, then don't panic - just take this thing one module at a time and start mapping it out.
You don't have to go all out and learn the whole thing up-front - take it one module or subsystem at a time, make plenty of diagrams about how the various parts of the business domain work from the perspective of the users, and do the same then for how they currently work. Put both diagrams side by side and start planning how you might refactor the code to be organised more like the business flow, and less like the existing flow.
This can be a tricky process for sure but actually once you get going, especially once you know how the system should ideally flow based on the previous point, it's not that bad - bear in mind that you will surely be able to copy/paste a lot of your existing code - in fact, you should probably avoid the temptation to try to fix bugs on the fly at this stage. Focus instead on the organisation of your classes, etc, so as to make then adhere to SOLID - any classes that broadly stick to this will typically be very testable.
Any bugs or really poorly written code can be flagged at this stage for fixing later on; a key point here is reaorganise not re-write!
Armed with that knowledge, the next step is to write a test specification for the various parts of the application, based on the new design of the modules. That means, lots of tests and test methods (using whatever framework you like, MSTest or xUnit, etc). You really can't avoid this but remember, one module at a time!
As DanielMann pointed out, it might be worth looking at something like Specflow that will let you write test specifications in a natural(ish) language form - you may even be able to get he stakeholders on board to help write the tests!
You don't have to have literally every detail specified at first; once you have identified the major "business units" in terms of logic, you can break them down into smaller and smaller chunks of conceptual behaviour
So you may end up with tests like (just an example)
LoginModule_WhenPasswordIsWrong_RedirectswithErrorMessage()
{
//write some code in here that exercises the LoginModule and assert that it behaves as expected
//The really important thing is to write these tests based on the NEW design
//and NOT the existing system.
Assert.Fail("Write the test!");
}
Now, the key thing here - most, if not all of these tests, will not even compile and even the few that do, will probably fail. That's actually a good thing! Because now you have a clear path of what you have to do - which is to make those tests pass by implementing the new design. Best to do this in a branch of the original!
So in the example above, you might not even have a clearly defined login "module" - the code might be scattered across several pages and classes. But by writing your "ideal" tests up-front, based on an ideal design, you now have a target to aim for. And also you don't have to be totally purist about it - there is no sin in bending the rules and making some tests less granular than the ideal case - you can come back and do that later.
Rinse and repeat - every system you do, is one less to do tomorrow!
Once your initial set of test methods is passing, you can then "zoom in" and start refining them, in the process fixing bugs and crappy code (the same thing, in many respects :) you came across earlier.
Best of luck with it!

Best practice for writing a custom portion of code?

Found thinking of a title a little tricky, but basically my question is how do you keep a system as generic (right term?) as possible when needing to write customer special code.
My scenario is that we have a standard system that lives in the trunk of subversion. Sometimes customers want to make a change that does not conform to that standard system, so our practice is to usually branch off the code and develop on that branch, but then it gets messy when trunk work needs to be included in a customer special or if an idea a customer wants needs to be in both the branch and trunk.
Is there a better way or standard to deal with such requests because it seems everything coded is very specific?
It's certainly a difficult scenario.
One option might be to have configuration to stipulate whether a feature is turned on or not - so the feature goes into the main branch but you only set the config to true for the customer(s) that require it. It's still a bit messy but I think it's cleaner than having multiple branches per customer.
In more complex scenarios you can develop new functionality as a type of 'plug in' architecture, where you have different implementations implementing the same interface - some type of factory could decide which to load.
I don't think there is any magic bullet for maintaining a generic code base which is subject to differing customer requests.
In terms of improving code re-usability, there are usually several parts:
Language Features
Being able to interchange smaller parts of an application is a core language design concern. Many languages are designed with methods of maximizing re-usability. Here are some examples (some are C# specific):
Interfaces
Generics
Co/Contra-variance
Dependency Injection
Design patterns (specifically, ones related to structure or creation)
They will allow you to reuse your codebase more easily but, on their own, aren't a golden bullet.
Project Design
Even if you exploit every feature available in C#, a insufficiently thought out project will probably be difficult to interchange. I'd reccomend any larger solutions should be split into logical, independant, subunits. Again, an example of a solution structure might be:
MyProgram // Wires up components and subunits.
MyProgram.Core // Contains a core 'kernel' for your application
MyProgram.IO // Contains generic interfaces and implementations for performing IO
MyProgram.UI // Contains UI code that displays and interacts with your core. The core should not depend on UI elements.
MyProgram.Models // Contains structure of databases, data models other components may act on
MyProgram.Models.Serialization // Converts your models for IO etc. Maybe you want MyProgram.IO to be generic enough to reuse.
Helpers // Generic helpers that you tend to use in multiple applications. You will want these to be in a standalone repository so that you can keep the classes validated.
Versioning
Ultimately, you may not be able to handle -every- problem with language features and good project design. If you have an awkward client request, sometimes you might want to pull (not branch) the components you -can- reuse and branch the ones you need to edit.

Hiding parts of my code from a programmer employee

I am working on a C# project and have two programmers to help me on parts of the project. The problem is that I don't trust these programmers as they are joining recently and need to protect my company's property.
I need to hide some parts of the code from the two programmers so they don't see it and they should still be able to work on their parts and run the full application to test it.
Is there such thing ? :)
Know a few things:
You Can't Hide Code Users Compile Against.
C# makes it incredibly easy to see what you're compiling against, but this is actually true for all programming languages: if they are required to compile it, compile against a dll, or they can run it, either as a DLL or as raw C#, they can get access to the logic behind it. There's no way around that. If the computer can run the program and it all resides on your PC, then the human can look it over and learn how to do it too.
HOWEVER! You can design your program in such a way that they don't need to compile against it.
Use Interfaces.
Make the code that the other employees must write a plug-in. Have them write their code as an entirely separate project to an interface that the core part of your API loads dynamically at run time.
Take a look at The Managed Extensibility Framework for a tool to do this.
Use Web or Remote Services.
Components of particular secrecy can be abstracted away so the details of how it works can be hidden and then invoked via a web call. This only works in situations where the core details you want to protect are not time sensitive. This also doesn't protect the idea behind the feature: the employee will need to understand it's purpose to be able to use it, and that alone is enough to rebuild it from scratch.
Build Trust Through Code Reviews.
If you don't currently trust your employees, you need to develop it. You will not be able to know everything that everyone does always. This is a key skill in not just programming, but life. If you feel that you can't ever trust them, then you either need to hire new employees that you can trust, or build trust in them.
One way to build trust in their capabilities is through code reviews. First, make sure you're using a version control system that allows for easy branching. If you aren't, switch immediately to Mercurial*. Have an "integration" area and individual development areas, usually through cloned branches or named branches. Before they commit code, get together with the employee and review the changes. If you're happy with them, then have them commit it. This will consume a little bit of time on each commit, but if you do quick iterations on changes, then the reviews will also be quick.
Build Trust Through Camaraderie.
If you don't trust your employees, chances are they won't trust you either. Mutual distrust will not breed loyalty. Without loyalty, you have no protection. If they have access to your repository, and you don't trust them, there's a good chance they can get at the code you want anyway with a little bit of effort.
Most people are honest most of the time. Work with them. Learn about them. If one turns out to be working for a hostile entity, they've probably already obtained what they wanted to get and you're screwed anyway. If one turns out to be a pathological liar or incompetent, replace them immediately. Neither of these issues will be saved by "protecting" your code from their eyes.
Perform Background Checks.
A further way to improve trust in your employee, from a security standpoint, is a background check. A couple hundred bucks and a few days, and you can find out all sorts of information about them. If you're ready to hide code from them, and you're the employer, you might as well do due diligence before they steal the secrets to the universe.
Your Code is Not That Important.
I hate to break it to you, but there's almost a 100% chance that your code is not special. Trying to protect it through obscurity is a waste of time and a known, poor, protection method.
Good luck!
**Why Mercurial? Just because it's one option that's easy to get started with. Feel free to use any other, like Git, if it suits your fancy. Which one you use is entirely besides the point and irrelevant to this overall discussion.*
You can't do it,
Even if you only give them a DLL with your code, they can extract the code with reflection tools, e.g. reflector.
Keep a separate backup and submit dummy placeholders to source control.
The complicated way: set up an application server with VS2010 and all the files they need, lock everything down so they cannot access any files directly and can only run VS2010 and the built application, and provide only DLLs for the protected code.
Theoretically, they would be able to work on the code they need to but would never have direct access to the DLLs, nor would they have the ability to install or use a tool such as .NET Reflector to disassemble the files... might still be some holes you'd need to look for though.
The right way: Hire trustworthy programmers. ;)
Put your code into a DLL and use Dotfuscator to obfuscate the internal workings.
The only way I can see is to give them compiled and obfuscated assemblies to reference. Because you can only obfuscate private members you may possibly need to modify your code so that public methods do not do much if anything at all. If there is any interesting code in a public method you should rearrange your code like this:
public bool ProcessSomething()
{
return this.DoProcessSomething();
}
private bool DoProcessSomething()
{
// your code
}
Even obfuscator that comes free with VS will do some job to make it non-trivial to look into your code. If you require more protection you need better obfuscator of course.
But in the long run it is impractical and sends bad signals to those developers telling that you do not trust them. There can be nothing good coming out of this. If you're not the boss (or owner of the code) I would not worry that much - after all it's not your property. You can talk to your boss to express your concerns. If you are the boss you should have not employed people you do not trust in the first place.

.NET security mechanism to restrict access between two Types in the same project?

Question
Is there a mechanism in the .NET Framework to hide one custom Type from another without using separate projects/assemblies? I'm not talking about access modifiers to hide members of a Type from another type - I mean to hide the Type itself.
Background
I'm working in an ASP.NET Website project and the team has decided not to use separate project assemblies for different software layers. Therefore I'm looking for a way to have, for example, a DataAccess/ folder of which I disallow its classes to access other Types in the same ASP.NET Website project. In other words I want to fake the layers and have some kind of security mechanism around each layer to prevent it from accessing another.
More Info and Details ...
Obviously there's not a way to enforce this restriction using language-specific OO keywords so I am looking for something else, for example: maybe a permission framework or code access mechanism, maybe something that uses meta data like Attributes. Even something that restricts one namespace from accessing another. I'm unsure the final form it might take.
If this were C++ I'd likely be using friend to make as solution, which doesn't translate to C# internal in this case although they're often compared.
I don't really care whether the solution actually hides Types from each other or just makes them inaccessible; however I don't want to lock down one Type from all others, another reason access modifiers are not a solution. A runtime or design time answer will suffice. Looking for something easy to implement otherwise it's not worth the effort ...
You could use NDepend to do this:
http://www.ndepend.com/
NDepend could allow you to enforce "layering" rules by specifying that certain namespaces should not reference each other. You then plug NDepend and the ruleset into your automated build, and it will fail the build (with a full report) if there are any misdemeanours.
In this way you can enforce logical software layering concepts within an assembly without having to use project structures to do it physically.
Update
I answered the question late last night, and rather literally i.e. how you can directly solve the question. Although a tool can be used to solve the issue, developing in one project across the whole team is more than likely going to be a pretty miserable experience as the project grows:
Unless people are incredibly disciplined, the build will keep breaking on layering violations.
There will be source control merge thrashing on the VS project file - not pleasant.
Your unit of re-use is very large and undefined if you want to share assemblies with other applications\projects you are developing. This could lead to very undesired coupling.
Although I do not advocate having lots of tiny assemblies, a sensible number defined around core concepts is very workable and desirable e.g. "UI", "data access", "business logic", "common library" and "shared types".
Nothing out of the box; there may be some 3rd-party tools that you can use to kludge some rules together, based perhaps on namespaces etc. Something like a custom fx cop rule...

How do you handle large projects? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I've just inherited a large project previously coded by about 4-5 people. The documentation consists of comments, and is not very well written. I have to get up to date on this project. How do I start? It consists of many different source files. Do you just dig in? Are there tools that can help visualize the structure/flow?
If you have a chance, I'd try and talk to the original designers and developers. Ask them about any major design issues or shortcomings of the project. Is the project in good shape and only needs maintenance or are there major components that need to be added or reworked? What are going to be the biggest roadblocks to maintaining the project? Take one or two of them to lunch (separately) if you have a budget for it as they might be more free to talk about problems outside of the office.
Talking to the users is also important for getting a feel for the current status of the project. Quite often they have a different opinion of how things stand then the developers do. Make sure, however, that they don't start giving you a list of all the things they want added or changed - you should take a few weeks to understand the project before you can start making major changes to it.
As for visualization tools, I'd start with the database design if there is a database involved. Tools like Microsoft Visio can create a diagram from an existing database. I find knowing the design of the database helps me wrap my head around what the programmers were trying to accomplish. Visio is also good for documenting program flow with some basic flowcharts though you'll have to create them yourself - it doesn't generate them automatically as far as I know.
Good luck.
I would encourage you to buy and read this book thoroughly. It provides you a LOT of information in this regard, much more than you will find here.
Brainstorming a little for you:
Step around in the application with a debugger, use a Static Code Analysis tool for which ever language you are working with...
Talk with people - both developers AND USERS to get a feel of the application.
Review the issue tracking system to see if you can see any recurring types of problem...
Are there tools that can help
visualize the structure/flow?
The latest Visual Studio 2010 allows you to generate architecture diagrams.
http://ajdotnet.wordpress.com/2009/03/29/visual-studio-2010-architecture-edition/
Try to find the starting point of the system and start digging from there. It sort of sucks to be in that situation, and chances are the comments might not be that helpful either. If the original developers didn't bother (or didn't have the chance) to document, chances are they never kept the comments up to date with code changes.
So time to bring the shovel... but don't just dig in blindly. One thing that is important is to understand what the system does from a users' perspective.
Concurrent with your code digging, you need to meet with a user (or the users' liason) and have him walk through the system, showing you how it is supposed to be used, for what purpose and what it and its subsystems are supposed to do. Moreover, attempt to understand what are the business pre-conditions and post-conditions of each major operation performed with this system.
Then map (or do a hierarchical) chart of the main functions of the system; classify them by category, purpose or module. If the system performs some sort of work flows or business transactions, attempt to chart some sort of state/transition diagram documenting each (and cross-referencing each state/transition to the subsystem or module in the system that is in charge for it.)
Once you have that, you can dig according to function. It will be best if you dig for a specific purpose, say, there is a bug fix to implement. You locate the logical module or category pertaining to that bug fix, you have the pre-conditions and post-conditions; then you can dig precisely on (or around) that bug fix.
If you just dig in without a guide (at least a high level one), you can be digging for months without getting anywhere (I'm telling you from painful experience.)
If there is no user manual, implement a draft according to your meetings with the users/users' liason. That could serve as a guide for implementing a developer's/administrator's manual for the system you just inherited (if there is ever a chance to implement one.)
If code is not on source control, put it on it. Doesn't matter what SCS you pick (could even be CVS, yuck!) What matters is to put it under source control asap.
Those developers didn't exist in a vacuum, they must have had exchanged emails. Identify other tech liasons they work with. Attempt to identify what other systems, if any, this system interfaces to (.ie. your databases, other's peoples databases, cron jobs, etc.)
But this could come at a later time. I think you should, for starters, focus on understanding how to use the system and what it is for. Let's call it understanding its business/knowledge architecture. Then dig according to that... or better yet, according to that and with the purpose of fixing a bug.
Good luck.
Use Profiler to see main functions and events in your project (the fastest way to learn framework)
Learn business logic very well to better understand the code
Documenting every new thing you learn - setup wiki (you will be surprised how quickly things are forgotten)
You can use Visio to draw Database Model Diagrams. (keep them close to you while studying the code)
These are the things that helped me when I inherited the previous project (50+ developers, 70+ GB database, 1 GB of source code and not even a single line of comments in code (maybe few :), and everything written in foreign language )
Use the debugger to walk through the application. That will let you go both deep and wide. You'll also be able to learn about how the code handles specific scenarios.
When you're ready to change something as #Jaxidian said, Working Effectively with Legacy Code is a great resource.
I was recently in a similar situation. What helped in my case was focusing on the changes I needed to perform on the project, and in the process of making those changes I learned about how the project is structured and so on. Sure, the first few tasks took a bit longer, but look on the bright side: I got stuff done and I got familiar with the project at the same time.
I'd suggest two things that may help:
Be productivity-driven. In other words, find a change that needs doing and use this to learn how that bit of the system works. Your changes may not be the most elegant without a whole-picture understanding of the software, but you will get work done within days/weeks.
Follow things from the user-interface. I.e if a change involves things a user does on a dialog, find that dialog in the code (relatively easy) and then work backwards to see what bits of the code provide data to the dialog, how the dialog interacts with the system, etc. Trying to find "where does X happen in the code" is very hard without good documentation, but finding "where is the code relating to this dialog" is quite easy and gives you an entry-point into the code.
Whenever I start a new project, I spend 2-3 days skim reading the code and making notes. I basically go through the entire solution from top to bottom and make a map in a text editor of each (significant) class in each project and what it appears to do.
The aim in doing this is not to completely understand the entire codebase, so don't worry if you feel you are not getting your head around it completely. The aim is that you end up with an index of where to go when you need to start on your first piece of work. You should also end up with a cursory picture of the solution in the back of your brain that will get filled in over the next couple of months. I always do this on the first few days as your superiors will not expect you to be productive during this time and you may never get another opportunity where you have the time to do so.
Also, do not rely on code comments for direction. Even with the best intentions they are often unmaintained and may lead to incorrect conclusions about what a class or section of code may do: a comment may lie but the code always tells the truth.
If you already have a team, you could charge each with a part of framework, and the result of their exploration should be registered somewhere, like a wiki. After that, give to each a task similar to something which is already done in the system (from the functional point of view)
For example: if a list of products is displayed in your app, you could display a list of orders (the complexity should be approximately the same), in the same manner it's done actually in the app. Than make it more interesting: try to edit it and save into DB.
Than switch the tasks and let the questions appear and than the first person who made the same task will show & explain how things are done.
Like that you'll see how the things are done pretty easy + your team will be up to date with this knowledge.
Presuming there is a database, start with the data model. Somewhere (Mythical Man-Month?) it was written "if I have your tables, I don't need to see your code."
Regarding potential tools, you may want to look into NDepend. It is a code-analysis tool, with an emphasis on highlighting the internal organization and dependencies of the code base (see this post for typical outputs), and spotting code quality issues. I have not used it personally, but Patrick Smacchia, one of the developers of the product, has a few posts where he applies NDepend to some classic apps (here is NUnit for instance) and discusses what it means, and I found them interesting.
Go and speak to the users or, read the manual and / or if one exists, go on a training course for the system (internal training departments will sometimes have put them together if there are lots of users).
If you don't know what it's meant to be doing then the chances of you being able to work out how it does it are close to zero.

Categories