Multiple DBML models best practice for class names - asp.net-mvc

Several of our apps use multiple databases from the example below - each in their own separate DBML file. The problem is, MVC by convention puts them all in namespace AppName.Models causing class name conflicts.
Which of the two options is the better fix and why:
1.) Putting them in separate namespaces. To keep stylecop/resharper happy, they would go in their own subfolder:
/Models
/Live
Live.dbml
LiveDataContext.cs
/Crm
Crm.dbml
CrmDataContext.cs
**but now in code, all uses of them have to be Live.Customer and Crm.Customer to differentiate between objects.
EDIT: The other main downside of this, is that I see no other sample code from experts that use sub folders in the Models folder. On top of that, in order to keep the same naming for Helper file code reuse - even apps that only use one database would need a subfolder in Models, which I certainly never see people doing in MVC
2.) Prepending all object names in one or both DBML designers with a prefix. This is my current approach. The Live database has Customer and Order objects, while the Crm database has CrmCustomer and CrmOrder. They all stay in the same namespace and /Models folder. This, however has two main drawbacks:
Quite a bit of prefix redundancy in accessing child objects: CrmCustomer.CrmOrders.First().CrmOrderType Marsha Marsha Marsha
In other apps which only use one database, we often omit the prefix - and then during code reuse or Helper files we have to do a lot of find/replace. This is particularly evident in Helper files that get added to every app like error/activity logging.
So I'd like to hear from other experts which of the two strategies they use, or something else entirely. It seems like a pretty common occurrence to have at least some name conflicts between databases. Thanks
Example table names:
Live Database:
Customer
Order
Address
Phone
Log
20 other tables
Intranet Database:
Customer
Order
Address
Phone
Log
20 other tables
CRM Tool Database:
Customer
Order
Address
Phone
Log
400 other tables

If I understand your problem correctly, you have two additional possible solutions:
You can modify the namespace of the entities generated by the DBML. Assuming you use T4 templates to generate them, you can right-click on the *.tt file, and go to properties. There is a namespace property that you can set to your own custom, and therefore unique, namespace:
MyCompany.MyProject.DataModels.Live
MyCompany.MyProject.DataModels.Intranet
MyCompany.MyProject.DataModels.CRM
A second, similar option would be to have each dbml and the generated classes be contained in their own project, and their own namespace associated with it. So in this case you would have three new projects:
Data.Live
Data.Intranet
Data.CRM
You would then add a reference to the projects when you want to consume them.
The benefit to this, in my opinion, is that it is very likely that tomorrow you could have a project that needs to reference Live, CRM, and a brand new database. In this case you would simply take a dependency on the projects you've already created (binary, or code -- my preference is binary, but YMMV), and that part of this 2nd project is complete.
In my opinion, do not decorate you classes (your option 2). That will be very difficult to maintain.
There is nothing inherently wrong with your option 1, and I have done that as well, but for most of my current solutions I create projects for the reusability factor.

So, I question the design that leads you to needing two identical databases in code. That aside, I think option 1 is better. Here is my reasoning:
The code is more reusable. If you ever need to seperate either model into another project, or remove one, you don't have to remove the prefixes anywhere. This offers clean separation.
Option 2 requires you to specify as well, you aren't avoiding this. However, if any class needs to access only one namespace, you only need to specify at the using level, and not in every single reference to the code. In classes that need both, you aren't avoiding the prefixses in either case. So option #1 wins out in the only case that matters.
I generally avoid type-prefixes as a rule. They are ugly.
Grumble, grumble, database design

Related

ASP.NET MVC - How to use code first and database first method in same project and with same context

I have a requirement that I have to use code first pattern (which I have to implement) along with database first (which exists in the current system).
Now the condition is I must not create a different context for new tables or any other changes which I make in the database but have to maintain current context from DB first pattern. Is it possible to create code first and DB first in the same project sharing the same context? Do I must manage .edmx file or is it possible to handle the database from code first pattern only? And that too with managing TransactionScope.
I need some suggestions on this.
There are some things that I learned from my above problem.
One cannot use the same context for Code first and Database first.
To use code first and database first in the same project, context must be different and irrespective of ConnectionString. (one can use either existing ConnectionString or make a new one)
It is not good practice to use two patterns at same, but if situation demands it, than one must have no choice. Therfore at last one can create POCO classes for code first, from database first so it can be useful.
TransactionScope be used with irrespective number of database connections and it will work properly.
If anything I am missing, than please add it so other can have better idea, or they could at least save their time.

Battle-hardened strategy for naming files and folders in asp.net mvc projects

In French, a "donkey bridge" is some apparent difficulty in a subject to be learnt that throws off newcomers - the donkeys. The expression is used with patronizing assurance by educators who know the difficulty is apparent, not real, and the donkeys just have to cross the bridge.
Well I'm the donkey, and I'm having real trouble settling down with the folder structure and "virtual" urls of asp.net mvc projects. Urls are now a blend of pseudo-path information, encoded in routes, and arguments, that resolve to controller classes that, being classes, have no notion of their directory. So, it seems, there is no simple way of using relative paths/urls to reference static resources associated with a dynamic page: script file, stylesheet, razor view, images. .Net helpfully gives me default search locations for views, and default folders for "Content", "Scripts", "Images". I get the feeling they want me to file things by type. But this obliges me to invent file and subfolder names in each of these locations, then to hardcode the resulting paths in the controller and the view. Since a given controller generally has only a handful of tightly coupled views, and 99.9% of views have 1 script file and 1 stylesheet, all this name invention, and categorization by type, introduces needless brittleness and complexity, and masks any expression of what the project actually does.
Is anyone else fighting this? Is their a tried-and-tested strategy for naming in large mvc projects that
Expresses what the project does at the top level of the folder structure (or any level of the folder structure!).
Provides a default location or generated names for .cshtml, .js and .css, such that I don't need to search through code to find the names of associated resources.
Preserves the flexibility and decoupling of naming/indirection where this has proved useful.
I'm aware of areas as a way subdividing an mvc project into functional groupings, but this just seems to recreate the problem inside each area. I've looked at this method for customizing the search location for views, but there's no dynamic element. I've implemented a view engine to have fine-grained run-time control over the view path, which is fine if you're brave but I'm still unsure how best to use it, and I'm put off by the potential caching issues. For all the dissing of opinions, I'm particularly interested in answers addressing what I should do.
Thanks to all the downvoters, intolerant village folk. The donkeys that refused to cross the bridge are right, and they're all hanging out in a green field, munching happily on Nancy and building fabulous Owin pipelines. Feature folders are the future.
I agree with you that trying to arrange elements by type is usually problematic. For example putting C# interfaces for a customer and a product in the same "Interfaces" folder is not something I am keen on personally, I'd rather have a Customers folder and a Products folder, each with an Interfaces folder inside.
However, with MVC, there is a lot of enforced and unenforced convention in place which you will probably have to live with. As an example, if you have a controller called ProductContoller, it will automatically look for views in the Views\Product folder. So your product index.aspx/cshtml view is nicely segmented from your other index views.
For things like scripts and CSS, these are not enforced and technically you could put them anywhere, but it's a convention across many web frameworks to keep them in the same root folder. In some frameworks you would be explicitly allowing public access to certain folders to read files, so you'd want to do this for all scripts or CSS files together.
It's not an answer but I hope it helps.
then to hardcode the resulting paths in the controller and the view
No.
Use UrlHelper (Url property in controllers and views). Extends it with ad-hoc functions for resolving your specific urls, as this blog post do.
For resolving views, stick to MVC conventions as explained in Dorian's answer.

Localization Strategy

We're currently debating two strategies of localization:
A. Have an XML file for the structure of the business objects with a Localized key to a separate CSV file for the translation.
for eg. /Resources/Schema.xml
in a separate CSV file: we have all key/value pairs for the translations:
/Resources/Localized.txt
Model_Title, Title, Title (in French), ...
This way, when the structure changes, we just change XML once while the LocalizedKey's are in place.
B. Have separate XML files for each language based on Culture.
eg. have two files:
/Resources/en-US/US-Localized.xml
/Resources/fr-AU/AU-Localized.xml
This way, they will have same schema but separate files. Therefore the user would have to make sure that the schemas are the same as they would need to change it twice as opposed to Option #1 where they can just change it once.
However, the readability here is much better since the user would not have to track the key the make the changes.
What are your thoughts/ideas on the strategies I suggested?
Thanks,
It is not clear about the environment -- web? desktop? internal enterprise integrated something-or-other? Is there any particular reason you aren't using whatever i18n framework your tool chain supports (gettext, .NET resource files...)?
In general I'd say you want to separate out resources by culture (but to be honsest, fr_AU should be rare) to have better maintainability and do not have to load the entire file for all per-culture-versions in many situations. This is especially true if your number of supported languages/cultures goes into the dozens or more.
However, it would be important to accommodate XML schema changes. The XML could be auto-generated, from simpler structures (key-value, either in a database or files) and validated via a common schema.
This is whether (as commenters noted) you are providing localized products or customers can create their own localizations.
In general, you should consider existing tools, rather than start from the scratch.
In .net we are using Data Driven ASP.NET Localization
Resource Provider and Editor Created by rick strahl

"inheriting" ASP.NET MVC sites from a common template app? (multi-tenancy)

We're building about 10 ASP.NET MVC sites which have a common set of features (and corresponding URLs, Routes, Controllers, Actions, and Views). The sites will also all share a base set of domain objects (e.g. users, companies) and base attributes on those objects (e.g. name, address, etc.).
But each site will also be highly customized and extended from the base. For example, our site for large, public companies will have "Subsidiary" and "Stock Symbol" fields on the Company domain object, while our site for startups will have a "Venture Firm" and and "Funding" attributes. Look and feel will also vary considerably, although we're trying to keep HTML as consistent as possible (modulo extra form fields for extra domain object attributes, etc.). We'll also be overriding images sparingly, so we can, for example, re-use the same button graphics across sites.
Anyway, we're trying to figure out how best to factor and architect things so that we can reuse as much code and as many tests as possible without limiting our freedom to add per-app attributes and vary the UI between apps.
I'm familiar with how to handle limited-customization multi-tenancy like you find in StackOverflow/SuperUser/ServerFault (or MSDN/TechNet for that matter), where the UI is a little different and the data model is more-or-less identical. But when the models and UI are very different (but inherit from a common base), I'm less sure how to proceed.
I'm less worried about operational issues, since we'll probably be running each site in a separate appdomain and hosting them on separate databases. I'm more worried about reducing long-term code maintenance costs, increasing agility (e.g. easy to add new features to the base without breaking derived apps), and realizing short-term dev-/test-cost savings as we build our 2nd, 3rd, 4th, etc. site.
I'm looking both for high-level guidance and suggestions, but also concrete suggestions for how to make that guidance real using modern ASP.NET MVC practices.
I realize this is a very general question, but for starters I'm looking for both high-level guidance as well as concrete tips-n-tricks for how to apply that guidance with ASP.NET MVC, including things like:
recommendations where to split base/derived across Visual Studio projects
source control tips to avoid forking
database schema tips (FWIW, our databases are all small-- under 10K rows per table, so dev/test cost is more of an issue than DB perf)
tips about re-using Controllers/Views/etc. corresponding to the "base" model attributes, especially re-using UI for things like "new customer" forms which will have a mix of base and derived attributes.
Anyone have good advice for how to architect a multi-tenant app like this?
Here's what we do, and it works pretty well for about 8 sites currently.
Define a core MVC project for your Controllers, ViewModels, HttpApplication, routes, etc. This will compile into a DLL and compromise the bulk of your site.
Create a basic set of default views, scripts, images, etc. for your site. These will server as defaults for your individual sites.
Per client, create any custom controllers, routes, etc that you'll need in a project that compiles to another dll.
Also per client, recreate any views, scripts, images that you'll want to use.
To make the above steps work together you'll need to write a little glue. The first piece of glue is a custom view engine. You'll want to customize the standard view engine to first look for views in your client-specific folder, and then the default folder. This lets you easily override the default layout per client.
The second method of getting everything working is to have your core application load the routes, controllers, etc from your client specific assembly. To do this I use the Managed Extensibility Framework (MEF) to expose a single Register method. Calling this method on my client assembly code registers the routes and any other client-specific needs.
Here's a general view of what my site folder structure looks like, with SiteContent being checked for views first:
- AppContent
- AppContent/Static
- AppContent/Static/Images
- AppContent/Static/Scripts
- AppContent/Static/Styles
- AppContent/Views
- AppContent/Views/Shared
- SiteContent
- SiteContent/Static
- SiteContent/Static/Images
- SiteContent/Static/Scripts
- SiteContent/Static/Styles
- SiteContent/Views
- SiteContent/Views/Shared
- web.config
- Global.asax
I have helpers that I can use like SiteImage and AppImage for use in my views. Also, I make each of my client sites use certain specific names for their master pages, that I don't ever define in my AppContent defaults.
I realize this is a rough overview, but it is working well enough for us right now.
I'm involved in a similar type of "suite" of projects currently which is focused on allowing customers to apply for products online but have very similar requirements for what information to collect, where the only differences are around product specific pieces of information or slightly different legislative requirements.
One thing that we have tried to do is create pages (model, view and controller combinations) that are reusable in themselves, so any application can use the page to capture information but redirect to the next page which may be different depending on what type of product is being applied for. To achieve this we are using abstract base controllers in the form of the template method pattern that contain basically all the required controller logic (including action methods with their applied action filters) but then use abstract methods to do the specific stuff such as redirecting to the next page in the process. This means that the concrete implementation of the controller used by specific application page flows may contain only one method which returns a RedirectToActionResult corresponding to the next page in the flow.
There is also quite a bit of other stuff that handles going backwards and those kinds of navigational things, but with the help of action filters you can get it set up that you don't have to worry about it once you get it up and working.
There are also base model objects which contains common functionality, be it validation logic or state persistence logic.
The data captured during the application process is persisted in database as xml serialized model objects which can then be pulled out and de-serialised once the application is completed and spat out in whatever format to whatever system the backend operations staff use to process applications.
The implications of this is that we have a project structure that consists of a base dll that contains top level abstract classes, interfaces and utility classes as well as html helpers, action filters etc. Then we have mvc projects which contain the concrete implementations of the base controllers, models etc as well as the views and masterpages.
The hardest thing is sharing views and I don't think we have properly got this sorted yet. Although with MVC 2.0 containing Areas I think this will become less of an issue but I haven't had a good play with it yet. (see Scott Gu's post on 2.0: http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx)
One thing I have POCed that looks like it will work is using a base MVC project to contain common views and then extending the default view engine to search that project on the web server when looking for a view to render (which is quite easy to do). Areas though is a far nicer solution.
As for source control, we are using svn and I think you are reasonable in being concerned about branches. It is not something that we have had to deal with yet, but we are probably going to go with git as it seems to make the process of branching and merging much less painful.
Not sure whether this helps you much but I would definitely recommend keep in mind abstract controllers and models, and also look at how you can use html helpers and and partial views to group similar pieces of functionality.
Mike Hadlow goes into good detail on how to accomplish this:
http://mikehadlow.blogspot.com/2008/11/multi-tenancy-part-1-strategy.html
One way to do this is to use branching in a source control system.
The main branch is for the common functionality. You then have a branch for customization and can merge changes out to the customization or back to the main branch.

DDD principlers and ASP.NET MVC project design

Two part questions
I have a product aggregate that has;
Prices
PackagingOptions
ProductDescriptions
ProductImages
etc
I have modeled one product repository and did not create individual repositories for any of the child classes. All db operations are handled through product repository.
Am I understanding the DDD concept correctly so far? Sometimes the question comes to my mind that having a repository for lets say packaging options could make my life easier by directly fetching a the packaging option from the DB by using its ID instead of asking the product repository to find it in its PackagingOptions collection and give it to me..
Second part is managing the edit create operations using ASP.MVC frame work
I am currently trying to manage all add edit remove of these child collections of product through product controller(sound right?).
One challenge I am now facing is;
If I edit a specific packaging option of product through
mydomain/product/editpackagingoption/10
I have access to the id of the packaging option
But I don't have the ID of the product it self and this forces me to write a query to first find the product that has this specific packaging option then edit that product and the revelant packaging option. I can do this as all packaging option have their unique ID but this would fail if I have collections that don't have unique ID.
That feels very wrong..
The next option I thought of is sending both the product and packaging option IDs on the url like;
mydomain/product/editpackagingoption/3/10
But I am not sure if that is a good design either.
So I am at a point that I am a bit confused. might be having fundamental misunderstandings around all of this...
I would appreciate if you bear with the long question and help me put this together. thanks!
In my mind, this is one of those muddy things that pops into DDD.
In code, I treat an aggregate root as a container for any "relationships" it has and any Entity Objects that cannot exist without the Aggregate root.
For instance, let's take the Customer->Order->LineItem->Product example that's been bludgeoned to death by now. The aggregate root as I've displayed it is customer in this scenario. That stated, you don't always want to get to the order through the customer. You might want to find orders on a specific date.
Turning it on it's side, you also wouldn't have a Customer that doesn't have an order. The two are in a somewhat symbiotic relationship so one isn't the aggregate root of the other.
The point is that you don't want to have to load a customer through an order, but you don't necessarily want to load an order through the customer either.
Starting at Order, however, it's unlikely that you'd want to just retrieve a LineItem and you're certainly not going to be creating them w/o an order. To that end, the Order serves as the gateway to LineItems. LineItems wouldn't need their own controller or repository. They only exist within the Order itself and, as such, are part of the Order (in this case, Order becomes the aggregate root) and are managed by the Order Entity.
But, a LineItem would likely have a relationship to a Product within the system. Products would have their own controllers, repositories, etc because they can exist outside of the Aggregate root.
In summary to my rambling, I tend to look at it this way: if an Entity can exist by itself, it should have a controller. Entities that cannot exist on their own (LineItems in this case) should only be managed solely by their container (aggregate root).
Will some DDD purist please correct me if/where I'm wrong?
As to the second part of your question, I would need some more details about how you envision these other Entities working. With what you've put here, I'd imagine that PackagingOptions are related to a product and would be part of a Product aggregate root. Now, implying that you're editing them begs the question of is this a lookup table in the system or are they one-off values and, as such, should be treated as Value Objects?
Kaivalya,
Regarding your last comment (stateless http):
It depends on the context. Before getting into the details, I should tell you a basic principle about aggregates:
Aggregates define a group of related objects that should be treated as a single unit for the purpose of data change.
This is extremely important. The purpose of having Aggregates is to enforce invariants. For example, you may have a policy like "An Order cannot exceed $500". Then, to enforce this policy, you put Order and OrderItem together in the Order Aggregate. This way, any time you add a new OrderItem, it should be added via Order object. There, you can check the total price and make sure it does not exceed $500. If you don't have such invariants in your domain, then there is no point loading all these objects together.
Now, getting back to your comment:
If you do have invariants that should be enforced, then it is okay to load the entire aggregate even though it may have some overhead. Yes, HTTP is stateless and you load your whole aggregate just for modifying one of its child objects and then throw it out. That is okay. What is important the most here is that you are enforcing your invariants. This is what DDD is for.
The purpose of DDD is to capture all business logics in your domain. You could definitely achieve a better performance if you didn't have to load the entire aggregate, but how would you enforce your invariants? You'd most likely have to do it in your stored procedure. Yes, it works, and it is fast, but dealing with business logics in stored procedures during maintenance is a nightmare. That is why DDD has evolved. So you can model your business requirements using object-oriented languages/tools, so they are easier to understand and modify.
Just remember, DDD is a great approach but not for all types of projects. If you are dealing with a project in which there are lots of business logics and the chances of them changing due to the nature of a business is high, then you should use DDD. However, if your project is more of a "read something/writing something" without much business logic involved, using DDD is a headache. You could simply use LINQ to SQL (or SqlDataAdapters) and send your objects to your Views. You don't even have to worry about finding Entities, Value Objects, Aggregates, Repositories, etc.
Hope this helps,
Mosh

Resources