Suggestions needed on an architecture for a multiple clients and customisable web application [closed] - asp.net

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Our product is a web based course managemant system. We have 10+ clients and in future we may get more clients. (Asp.net,SQL Server)
Currently if one of our customers need extra functionality or customised business logic, we will change the db schema and code to meet the needs.
(we only have one branch code base and one database schema)
To make the change wont affect each others route, we use a client flag, which defined in a web config file, thus those extra fields and biz logic only applied to a particular customer's system.
if(ClientId = 'ABC')
{
//DO ABC Stuff
}
else
{
//Normal Route
}
One of our senior colleagues said, in this way, small company like us can save resources on supporting multiple resources.
But what I feel is, this strategy makes our code and database even harder to maintain.
Anyone there crossed similar situation? How do you handle that?
Update:If this is not a right question for SO, can someone move this question to a proper stackexchange site?
Update2:
you are right. The code is becoming smelly now, and I quite sure will be a nightmare sooner or later. Our company is doing the product and to save the effort, later products for other customers are based on the previous one. I know the ideal way is seperate the #e-j-brennan dev teams into 2 parts. One team works on core product and made it highly customisable, and team two works on customising for a particular client. However if since our company is so small, it is really a dilemma situation. :(

I think you need to decide if you sell custom software, that you tailor for each client, or 'off-the-shelf' software that is one-size-fits-all (and maybe customizable thru functionality you provide).
When you only have a handful of clients like you do now, you can get away with what you are doing, but I can almost guarantee that if you continue down this road, and your client base increases and the amount of client-specific customization's increases as well, you will have a nightmare on hand; I've been thru this many times for multiple clients, and it always ends the same way. It all is manageable until it is not, and then it is a royal pain-in-the-neck that could make your life very difficult indeed.
If you decide you are a custom company, and want to have multiple versions of the software and database, that is fine, just make sure you charge the full cost for it - i.e. factor in that you may need to maintain multiple levels of source code and databases and factor in that upgrades are going to take many multiples of effort to rollout as you will need to test each client's code base.
If you decide you want to be an 'off-the-shelf' type of product, then your best bet is provide the ability for each client to customize their experience, without the need for code changes - i.e. built in the customization capability thru config screens and tables that control how things work - but everyone will still use the same underlying code and database. Much more work upfront, but saves you boatloads of time down the road.

I have also been in your position, and I agree it is a difficult one. In my case, I was building custom single-product sites for clients. While each site followed a similar layout and workflow, there had to be enough flexibility for each to have a wholly custom design, custom rules around shipping and coupons, and different merchant gateways and configurations.
After some years, we did end up with something maintainable. First, we created libraries to house all of our common code and put those libraries into a TFS project simply called Common. Then, we created a new TFS project for each site (not client, as many clients had multiple products/sites) and branched the applicable projects into them from Common. Next, we created a VS Template project that contained a skeleton of the site, including "design-less" views, controllers, and their action methods (remember, each site had the same basic flow). Also, each site ran on its own database, which was cloned from an otherwise unused and mostly empty Template DB.
With each site running on its own branch and DB, modifications could be made to the original flow and design that was installed by the template (which would never need to be merged back in) without affecting any other site. For customizing business methods, like shipping calculations, we could create a subclass of the common class and override where needed. Part of what enabled this was converting all our code to use Dependency Injection. Specifically, each Controller had injected Services, and each Service had injected Repositories. Merchant Processing was also coded to an interface and injected. Also worth mentioning is that this allowed us to hard-code all of the upsell logic for each site (you bought product X, so we recommend Y), which was much easier to create and maintain compared to defining complex configuration rules in our old upsell rule engine. I don't know if you have anything like that...
Sometimes we would want to make a change to the Common code itself, which was usually prompted by a specific need for a specific site. In that case, we'd make the change on that branch, merge it to Common, and then merge it to the other sites at our convenience (great for "breaking" changes or changes that also required a change to the DB). Similarly for DB changes, we would update the Template DB and then write a little script to update the other site DBs with the same schema changes ( still had to be smart and careful about it).
An added benefit was that we also created Mock repositories that would be used/injected in a "Design" build configuration, which enabled the designers to jump around the application and work on screens without literally submitting themselves to the workflow. It also allowed them to start working on a site before there was anything done on the back-end, which was very important for those anxious clients who need to "see something".
10+ clients is definitely not a small number with what you're talking about. Three was pain enough for me. We had over 30 sites running at one time, maintained by three developers and two designers.
Finally, I know it's outside the scope of your question and a bit presumptuous, but getting "final" client sign-off on design before the designers actually went about implementing it (and before devs did their thing) also saved us a lot of costly rework. I know no design is final, but increasing efficiency on the implementation end gave the clients less time to change their minds about the design they approved.
I hope that at least gives you some approaches to think about.

People working with systems that have to change or be customized, have developed patterns to handle such concerns.
You should definitely start by reading a good book on Inversion of Control. In short, you can build your systems by defining building blocks (contracts, expressed as interfaces) and provide multiple implementations. There are multiple benefits of such approach but to mention just two:
- you can handle customizations by providing diffent implementations of the same interfaces
- you can reconfigure your application statically or dynamically but both approaches are far more clean than your "if"
When it comes to the data layer, study the repository pattern. It helps to organize the data access in a way that you can switch between different providers. It fits great wiht ioc.
And just a technical tip - nhibernate supports dynamic properties. You just provide additional columns in the mapping and nh is able to support it from the same code base. This way you can target different databases with slightly different db schemas.

Related

Designing an Asp.Net MVC application

As a novice to this realm, I am planning on building an mvc application. I had originally started a web forms application but decided the scalability and testability will benefit more with an mvc application. I chose to switch with the added benefit of being easier to add more features later on (instead of having code baked into web forms pages).
Now a little about my application, it is an application to stimulate an RPG class builder and moveset. In all simplicity, users can register for a class, and depending on other skills they can register for, they can see a custom move set based on these categories. The way I am envisioning it is I will be able to go back and add more classes and skills later in the database and have users register for this new content immediately once it has been added to the project.
Everything lives in normalized tables, so many joint tables do exist. For each new skill or class I add will mean a handful of tables will be added to the database. This speaks to the way the data will be stored, everything and all information about classes, user data, skills, etc will be stored in the database.
I have designed all the initial database tables I will need to have at the start, and functionality I need (a home page, view skills page, view move sets page, etc.). I am stuck at the next step; where do I go? Should I make my controllers first? Models? Views? Design my page layouts? I am asking for advice from people who have taken a similar organic approach to an mvc project. I am facing analysis paralysis on what to start on, knowing I have a lot of work ahead of me.
Thank you for taking your time to answer.
I've taken everyone's advise and am putting together a website to learn MVC: http://learnaspnetmvc.azurewebsites.net
The most important advice I can give you: just start. A big project can seem overwhelming, especially when you're looking at it like a big project. Instead, break it into small achievable tasks. Find something you can do right now, the ever-so-smallest subset of functionality, and do it. Then do the next one. And the next.
That said, I'll tell you my personal process. When I start on a new application or piece of an application, I first like to create my models. That way I can play with the interactions between them, flesh out the relationships, and think about the needs of my application in a somewhat low-pressure, easily disposable way. I also use code-first, whereas you've gone an created your database tables already. Some people prefer to do it that way. Personally, I find starting with my classes and letting those translate into an underlying data store much more organic. In a sense, it relegates the database to almost a non-existent layer. I don't have to think about what datatype things need to be, what should be indexed and what shouldn't, how querying will work, what kind of stored procedures I need, etc. Those questions have their time and place -- the nascent development stage is not that time and place. You want to give your brain a place to play with ideas, and classes are a cheap and low-friction medium. If an idea doesn't work out, throw the class away and create a new one.
Once I have my models, I like to hit my controllers next. This lets me start to see my models in action. I can play around with the actual flow of my application and see how my classes actually work. I can then make changes to my models where necessary, add additional functionality, etc. I can also start playing around with view models, and figuring out what data should or should not be passed to the view, how it will need to be displayed (will I need a drop down list for that? etc.), and such. This, then, naturally leads me into my views. Again, I'm testing my thinking. With each new layer, I'm hardening the previous by getting a better and better look at how it's working.
Each stage of this process is very liquid. Once I start working on my controllers, I will make changes to my models. Once I hit the views, the controllers will need to be adjusted and perhaps the models as well. You have to give yourself the freedom to screw up. Inevitably, you'll forget something, or design something in a bone-headed way, that you'll only see once you get deeper in. Again, that's the beauty of code-first. Up to this point, I don't even have a database, so any change I make is no big deal. I could completely destroy everything I have and go in a totally different way and I don't have to worry about altering tables, migrating data, etc.
Now, by this point my models are pretty static, and that's when I do my database creation and initial migration. Although, even now, really, only because it's required before I can actually fire this up in a browser to see my views in action. You can always do a migration later, but once you're working with something concrete, the friction starts to increase.
I'll tend to do some tweaking to my controllers and obviously my views, now that I'm seeing them live. Once I'm happy with everything, then I start looking at optimization and refactoring -- How can I make the code more effective? More readable? More efficient? I'll use a tool like Glimpse to look at my queries, render time, etc., and then make decisions about things like stored procedures and such.
Then, it's just a lot of rinse and repeat. Notice that it's all very piecemeal. I'm not building an application; I'm building a class, and then another class, and then some HTML, etc. You focus on just that next piece, that small chunk you need to move on to the next thing, and it's much less overwhelming. So, just as I began, I'll close the same: just start. Writers have a saying that the hardest thing is the first sentence. It's not because the first sentence is really that difficult; it's because once you get that, then you write the second sentence, and the third, and before you know it, you've got pages of writing. The hardest part is in the starting. Everything flows from there.
The other answers here have great advice and important nuggets of information, but I think they do you a disservice at this stage. I'm the first to advocate best practice, proper layering of your applications, etc. But, ultimately, a complete app that follows none of this is more valuable than an incomplete app that incorporates it all. Thankfully, we're working with a malleable medium -- digital text -- and not stone. You can always change things, improve things later. You can go back and separate your app out into the proper layers, create the repositories and services and other abstractions, add in the inversion of control and dependency injection, etc. Those of us who have been doing this awhile do that stuff from the start, but that's because we've been doing this awhile. We know how to do that stuff -- a lot of times we already have classes and libraries we drop in for that stuff. For someone just starting off, or for an app in its earliest nascent stage, it can be crippling, though. Instead of just developing your app, you end up spending days or weeks pouring through recommendations, practices, libraries, etc. trying to get a handle on it all, and by the end you have nothing really to show for it. Don't worry about doing things right and do something. Then, refactor until it's right.
As a first step in planning a MVC framework application, We should start with a strong Model (typical C# props). This process is going to take most of our time, based on the fact that we need to understand the business first and then the relationships between different workflows and entities. So times business models evolve as time passes. So spend qualitative time on building this layer, but not too much.
Once domain (Business) Models are ready, before we actually start coding for Repository classes, we should define our Repository Contracts which are typically Interfaces. Contracts help all parties(other components) to interact with each other in the exact same way. Then we implement contracts on the Repository component, which is just going to act like PUSH and PULL data from your persistent medium (say database). Remember repository component never going to have any idea on business logic.
Once backend has been established, We can concentrate on my actual business process implementation. We can define one more level of Contract which defines all business operations which are to be done using Model classes. This interface has been implemented by BusinessLogic Component which does the core business activity (specific methods for every business operation). This particular component will use Repository component to delegate business data to persistence medium.
With above step completed, We can easily go and build Controllers. We should be calling business logic component methods in controllers and get work done. Once controllers are done, we can define our views and other UI elements like partial views etc.
Pictorial representation of the flow is as follows -
A simple architecture (from high to low level)
Presentation Layer
Domain Logic Layer
Data Access Layer
Database
Presentation layer is MVC project containing Views, Controllers and optional View-Models.
Domain Logic Layer is Class Library project which Presentation layer will access (via DLL or Service reference). This layer contains business logic and rules for the application.
Data Access Layer may contain two sub-layers-
Repository. User repository is best practice for any long term application.
Entity Framework Model.
This will communicate with database.
Database you already have.
I would suggest reading through a book by Scott Millet, called Professional ASP.NET Design Patterns.
ISBN : 0-470292-78-4
Scott walks through what a good ASP.NET site should look like from an architectural standpoint - i.e. DataAccess layers, Business Logic layers, Presentation Layers, Domain events etc.
By following on from industry standards, you will gain a better knowledge of how to correctly put together an MVC web-site.
Hope this helps.
I would suggest you to make your MVC application around a ASP.NET Web API , since it will help, in case you go for a mobile application later.
Since you are a MVC newbie, you should download some open source projects on MVC shared by seniors in the community. Study two or three projects, and analyze a solution which will the best for you.
A quick googling will get you to some good projects.
e.g.
Making a simple application , Prodinner
After that you should also go through MSDN tutorial on MVC 5 app with SSO , to enable social logins.

How to structure a proper 3-tier (no ORM) web project

I m working on a legacy web project, so there is no ORM(EF,Nhibernate) available here.
The problem here is I feel the structure is tedious while implementing a new function.
let's say I have biz Object Team.
Now if I want to get GetTeamDetailsByOrganisation
,following current coding style in the project,I need:
In Team's DAL, creat a method GetTeamDetailsByOrganisation
Create a method GetTeamDetailsByOrganisation in the Biz Object Team, and call the DAL method which I just created
In Team's BAL, wrap up the Biz object Team's method in another method,maybe same name, GetTeamDetailsByOrganisation
Page controller class call the BAL method.
It just feels not right. Any good practice or pattern can solve my problem here.
I know the tedium you speak of from similarily (probably worse) structured projects. Obviously there are multiple sensible answers to this problem, but it all depends upon your constraints and goals.
If the project is primarily in maintenance mode with very no new features being added I might accept that is the way things are. Although it sounds like you are adding at least some new features.
Is it possible to use a code generator? A project I worked on had a lot of tedium like this, which apparently was caused because they originally used a code generator for the code base which was lost to the sands of time. I ended up recreating the template which saved me a lot of time, sanity, and defects.
If the project is still under active development maybe it makes sense to perform some sort of large architectural change. My current project is currently in this category. We're decoupling code and adding repositories as we go. It's a slow process that takes diligence and discipline by the whole dev team. Each time a team takes on a story they tax that story with rewriting some of the legacy code in that area. To help facilitate this we gave a presentation to the rest of the team to get buy-in and understanding. We also created some documentation for our dev team that lists out the steps to take and the things to watch out for. In the past 6 months we've made a ton of progress. We don't have the duplication you speak of, but we have tight coupling issues which makes unit testing impossible without this refactor.
This is less likely to fit your scenario, but it may also be a possibility to take certain subset of features and separate those out into separate services that can be rewritten using a better platform and patterns. The old codebase can interoperate at the service layer if needed. You likely make changes in certain areas more than others, so the areas of heavy change might be top priority to move to a dedicated service. This has the benefit of allowing you to create a modern code base without having to rewrite the entire application from scratch all at once. This strategy is what Netflix has done to rewrite their their platform as they go and move it to the cloud.

Refactoring an ASP.NET 2.0 app to be more "modern" [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 6 years ago.
Improve this question
This is a hypothetical scenario. Let's say you've just been hired at a company with a small development team. The company uses an internal CRM/ERP type system written in .NET 2.0 to manage all of it's day to day things (let's simplify and say customer accounts and records). The app was written a couple of years ago when .NET 2.0 was just out and uses the following architectural designs:
Webforms
Data layer is a thin wrapper around SqlCommand that calls stored procedures
Rudimentary DTO-style business objects that are populated via the sprocs
A "business logic" layer that acts as a gateway between the webform and database (i.e. code behind calls that layer)
Let's say that as there are more changes and requirements added to the application, you start to feel that the old architecture is showing its age, and changes are increasingly more difficult to make. How would you go about introducing refactoring steps to A) Modernize the app (i.e. proper separation of concerns) and B) Make sure that the app can readily adapt to change in the organization?
IMO the changes would involve:
Introduce an ORM like Linq to Sql and get rid of the sprocs for CRUD
Assuming that you can't just throw out Webforms, introduce the M-V-P pattern to the forms
Make sure the gateway classes conform to SRP and the other SOLID principles.
Change the logic that is re-used to be web service methods instead of having to reuse code
What are your thoughts? Again this is a totally hypothetical scenario that many of us have faced in the past, or may end up facing.
You missed the first step that I would go through:
Cost-Benefit Analysis
Refactoring an app because you think it feels old is not a good reason. It's still running (I'm guessing fairly reliably by this point) and your company already has a lot of time and money invested in the code.
You probably also have a team of developers that are familiar with .NET 2.0 and WebForms whereas many may not understand the concepts/code you're trying to introduce.
Before changing anything, figure out how much money is invested, how much money you're going to spend on your changes, and how much money it'll save in the future...
If the numbers don't add up, no business is going to let you proceed.
Make sure you have a complete suite of tests to cover the existing code before you go tearing it up.
Write new features using your new techniques.
Update old code to the new techniques if it needs modification because of a feature request.
Refactor old code that doesn't need changes only if you are bored and have no new features to write.
While it can be tempting, I personally would not make these major changes to the architecture of the application unless they are satisfying specific user requirements. Simply implementing these to make the application better in terms of maintainability sounds like a big risk. You may get 60% of the way through and find major challenges with getting one of these changes to integrate with the rest of the legacy application. It sounds like you'd almost be facing a complete rewrite of the application to ensure everything is consistent with the new architecture. You may invest a lot of time into the rewrite, and find that the maintainability has only improved a little such that recapturing the time invested in the rewrite will take a long time.
If it were really poorly written or in a legacy language like VB6, I would personally say it would be a candidate for a major rewrite. However, .NET 2.0 is a very capable language and for alot of applications is not crippled. From your description it sounds like the application is pretty well designed as is. It actually has a data access layer, business objects, and is layered in some way. This sounds like a pretty good application considering you can identify these attributes. Consider yourself luck that this isn't some app where it's such a mess you can't pick out anything that resembles a particular design pattern.
Maybe there are places where the things are a little nasty, but sometimes it's not pretty where the rubber meets the road and things get wired together.
I agree with other posters, dont rewrite unless you can demonstrate the cost saving benefits.
What you could do is write new areas of the system using eg entity framework, MVC and jQuery because the difference will be transparent to browser users. In time you can move the legacy code over bit by bit as you make upgrades/enhancements.
Its also always easier to implement new technologies on new system code, rather than porting existing code.

How many apps should an internal development group be building/maintaining?

I've always been of the opinion an internal development group should really only be building/maintaining three applications.
An internal composite/pluggable/extendable application.
The company website.
(Optional) A mobile version of #1 for field employees.
I'm a consultant, and everywhere I go, my clients have dozens of one-off applications in the web and on the desktop for every need no matter how related to the others. Someone comes to IT and says "I need this", and IT developers turn around and write another one-off ASP.NET application, or another WinForms app.
What's your opionion? Should I embrace the "as many apps as we want/need" movement? I assume it's common; but is it sensible?
EDIT:
A colleague pointed out that it depends on the focus of the development - are you making apps or are you making a system? I guess to me, internal development is about making a system; development of shippable software products, like MS Word, iTunes, and Photoshop, is about making apps.
All of them?
Wow do I ever agree with you. The problem is that many one-off applications will (at some point) each have many one-off maintenance requests. Anything from business rule updates to requests for new reports. At some point the ratio of apps that need to be maintained to available development staff is going to be stretched/taxed.
From my perhaps (limited?) vantage point, I'm starting to think #1 and #3 could be boiled down to Sharepoint. Most one-off applications where I work (a large 500+ attorney law firm) consist of one or more of the following:
A wiki
A blog
Some sort of list (or lists joined together in some type of relationship), which can be sorted and arranged in different ways.
A report (either a Sharepoint data view or a SQL Server Report work just fine)
Or, the user just wants to "make a web page" and add content to it. But only they should be able to edit it. Except when they're out of the office, and then, etc...
Try to build any one of the above using [name your technology], and you've got lots of maintenance cycles to look forward to (versus a relatively minor Sharepoint change).
If I could restate what I think is your point: why not put most of your dev cycles to work improving and maintaining a single application that can support most of your business' one-off needs, rather than cranking out an unending stream of smallish speciality apps?
This question depends on so many things and is subjective besides. I've worked at companies that have needed several different apps because we do business in discreet silos. In that case, an internal group may not build and maintain apps, but may build several, with another group that is responsible for maintenance.
Also, what do you mean by "app"? If you broaden the term enough, then you could say "it's all just one big app".
In short, I think the main consideration is the capacity of the group and what business needs are.
I think there should be internal development teams that each has a system which may contain multiple applications within it. To take a few examples of what I mean by systems:
ERP - If you are a manufacturer of products, you may need a system to keep track of inventory, accounting of books and money, and other planning elements. There are a wide range of scales of such systems but I suspect in most cases there is some customization done and that is where a team is used and may end up just doing that over and over if the company is successful and a new system is needed to replace the previous one as these can take years to get fully up and running. The application for the shop floor is likely not the same one as what the CFO needs in order to write the quarterly earnings numbers to give two examples here.
CRM - How about tracking all customer interactions within an organization that can be useful for sales and marketing departments? Again, there are many different solutions and generally there is customizations done which is another team. The sales team may have one view of the data but if there is a support arm to the company they may want different data about a customer to help them.
CMS - Now, here I can see your three applications making sense, but note what else there is beyond simple content.
I don't think I'd want to work where everything is a home grown solution and there is no outside code used at all. Lots of code out there can be used in rather good ways such as tools but also components like DB servers or development IDEs.
So what's the alternative to several one-off applications? One super-huge application that runs everything and everything? That seems even worse to me...

Are there specific "technical debts" that are not worth incurring? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
There are (at least) two ways that technical debts make their way into projects. The first is by conscious decision. Some problems just are not worth tackling up front, so they are consciously allowed to accumulate as technical debt. The second is by ignorance. The people working on the project don't know or don't realize that they are incurring a technical debt. This question deals with the second. Are there technical debts that you let into your project that would have been trivial to keep out ("If I had only known...") but once they were embedded in the project, they became dramatically more costly?
Ignoring security problems entirely.
Cross-site scripting is one such example. It's considered harmless until you get alert('hello there!') popping up in the admin interface (if you're lucky - script may as well silently copy all data admins have access to, or serve malware to your customers).
And then you need 500 templates fixed yesterday. Hasty fixing will cause data to be double-escaped, and won't plug all vulnerabilities.
Storing dates in a database in local timezone. At some point, your application will be migrated to another timezone and you'll be in trouble. If you ever end up with mixed dates, you'll never be able to untangle them. Just store them in UTC.
One example of this is running a database in a mode that does not support Unicode. It works right up until the time that you are forced to support Unicode strings in your database. The migration path is non-trivial, depending on your database.
For example, SQL Server has a fixed maximum row length in bytes, so when you convert your columns to Unicode strings (NCHAR, NVARCHAR, etc.) there may not be enough room in the table to hold the data that you already have. Now, your migration code must make a decision about truncation or you must change your table layout entirely. Either way, it's much more work than just starting with all Unicode strings.
Unit Testing -- I think that failing to write tests as you go incurs a HUGE debt that is hard to make up. Although I am a fan of TDD, I don't really care if you write your tests before or after you implement the code... just as long as you keep your tests synced with your code.
Not starting a web project off using a javascript framework and hand implementing stuff that was already available. Maintaining the hand written javascript became enough of a pain that I ended up ripping it all out and redoing it with with the framework.
I really struggle with this one, trying to balance YAGNI versus "I've been burned on this once too often"
My list of things I review on every application:
Localization:
Is Time Zone ever going to be important? If yes, persist date/times in UTC.
Are messages/text going to be localized? If yes, externalize messages.
Platform Independence? Pick an easily ported implementation.
Other areas where technical debt can be incurred include:
Black-Hole Data collection: Everything goes in, nothing ever goes out. (No long-term plan for archiving/deleting old data)
Failure to keep MVC or tiers cleanly separated over the application lifetime - for example, allowing too much logic to creep into the View, making adding an interface for mobile devices or web services much more costly.
I'm sure there will be others...
Scalability - in particular data-driven business applications. I've seen more than once where all seems to run fine, but when the UAT environment finally gets stood up with database table sizes that approach productions, then things start falling down right and left. It's easy for an online screen or batch program to run when the db is basically holding all rows in memory.
At a previous company they used and forced COM for stuff it wasn't needed for.
Another company with a C++ codebase didn't allow STL. (WTF?!)
Another project I was on made use of MFC just for the collections - No UI was involved. That was bad.
The ramifications of course for those decisions were not great. In two cases we had dependencies on pitiful MS technologies for no reason and the other forced people to use worse implementations of generics and collections.
I classify these as "debt" since we had to make decisions and trade-offs later on in the projects due to the idiotic decisions up front. Most of the time we had to work around the shortcomings.
While not everyone may agree, I think that the largest contributor to technical debt is starting from the interface of any type of application and working down in the stack. I have come to learn that there is less chance of deviation from project goals by implementing a combination of TDD and DDD, because you can still develop and test core functionality with the interface becoming the icing.
Granted, it isn't a technical debt in itself, but I have found that top-down development is more of an open doorway that is inviting to decisions that are not well thought out - all for the sake of doing something the "looks cool". Also, I understand that not everyone will agree or feel the same way about it, so your mileage might vary on this one. Team dynamics and skills are a part of this equation, as well.
The cliche is that premature optimization is the root of all evil, and this certainly is true for micro-optimization. However, completely ignoring performance at a design level in an area where it clearly will matter can be a bad idea.
Not having a cohesive design up front tends to lead to it. You can overcome it to a degree if you take the time to refactor frequently, but most people keep bashing away at an overall design that does not match their changing requirements. This may be a more general answer that what your looking for, but does tend to be one of the more popular causes of technical debt.

Resources