Dave Laribee

Sponsors

The Lounge

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Folder != Namespace

Update: turns out this is a R# feature not a VS feature. Thanks Andy! 

Here's something I discovered in Visual Studio some time ago:

 

Seems you can select one or more folders and turn off their "namespace provider." This can save you a few keystrokes if you don't want folders to equal namespaces. This is very useful for my team. Say we have a class:

XEVA.UI.Smart.Views.ShellView.cs

And this class lives in a folder:

UI.Smart\Views\Shell

By default Visual Studio will add "Shell" to the namespace above. Not a big fan of this; want to keep my namespaces relatively flat. At the same time I want folders to logically contain only a few classes that logically belong with one another. Setting the namespace provider to false makes it so that subsequent views I might add get the right namespace and I don't have to go cutting out bits of text.

Sure, it's not Vim magic, but I think I can safely file this one under developer lifehacks.


Posted 12-18-2007 10:49 AM by Dave Laribee

[Advertisement]

Comments

Jimmy Bogard wrote re: Folder != Namespace
on 12-18-2007 12:16 PM

When you break from the namespace/folder convention, do you have an alternate convention you like to use?  Is there a reason you don't want the extra namespace?

One reason I like the folder/namespace convention is that it can be easier to discern the project structure from looking at the solution explorer.  A project I inherited worked out so that assembly name != root namespace != project name, which led to several different root namespaces.  When I wanted to add a class, I had no idea where to put it (the app is a big ball of mud already), as just about every file in a folder had a different namespace.

Doesn't Java force package structure to match physical disk structure, too?

Tomas Restrepo wrote re: Folder != Namespace
on 12-18-2007 12:17 PM

Hey, that's a pretty cool trick I didn't know about. However, the property doesn't seem to appear for me when I select folders, what's the trick? (R#?)

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 12:21 PM

Good point...

I follow the convention pretty much everywhere EXCEPT in our UI (windows forms, MVP).

So a typical presenter needs:

1. Presenter itself

2. Callback interface for separated interface

3. View interface

To mix these in one folder would be a bit untidy for us as we have A LOT of presenters. So presenters have their own convention:

Project = UI.Smart

Presenters\

Presenters\Admin

Presenters\Admin\Users

Presenters\Admin\Users\Add

Presenters\Admin\Users\Modify

Presenters\Admin\Users\List

Still I want the namespace for any type that collaborates to fulfill a presenter (above) to be "Project.UI.Smart.Presenters.Type1"...

Make sense?

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 12:22 PM

@Tomas - hmm... didn't think about that. Might be R#. Not willing to uninstall to find out though :) Also, this is in VS 2005.

Dave Foley wrote re: Folder != Namespace
on 12-18-2007 12:51 PM

This is also helpful to control the names of embedded resources.

Nick Parker wrote re: Folder != Namespace
on 12-18-2007 12:54 PM

Don't forget the associated keyboard acellerators to make this happen:

ctrl + alt + L = Got to Solution Explorer

shift + arrow up/arrow down = Select folders

F4 = Switched to the Properties tab

Arrow down = Go to Namespace Provider

Tab = Edit value assignment

My 2 cents.  :-)

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 1:20 PM

@dave - good tip.

@nick - heh... if it's worth doing, it's worth over doing?

Bryan Watts wrote re: Folder != Namespace
on 12-18-2007 3:22 PM

Folders as namespaces gives you a structural representation of a logical grouping. Otherwise, you must do a lot of mental mapping based on specialized knowledge - it's just more work for your brain.

I like splitting a namespace across assemblies, where each is a feature rooted in the same default namespace.

It achieves logical grouping and physical alignment, and merges nicely when a developer opts-in via a reference at the project level.

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 3:38 PM

@brian - sure. in my case, though, it's just plain wrong to have a namespace per presenter. doesn't make sense when consuming those presenters from the outside. they all belong in the same namespace. but... and here's the rub... as each presenter needs a view interface and a callbacks interface you end up with cohesive elements spread apart in one folder as interfaces, by convention start with "I". so this feature, while generally not applicable, does have its uses. IMHO anyway.

Nick Parker wrote re: Folder != Namespace
on 12-18-2007 3:45 PM

@dave - fair enough.  :-)

Bryan Watts wrote re: Folder != Namespace
on 12-18-2007 4:31 PM

I didn't suggest a namespace per presenter. That's akward. I agree they should all reside in "Project.UI.Smart.Presenters".

I am saying you can accomplish this while still using namespace folders. You don't have to break from convention and you get all your requirements met.

Let's be concrete: it looks like you have 3 "nouns" per presenter: itself, the callback interface, and the view interface. So "Users" would expand to something like

Users\Add\[3 things]

Users\Modify\[3 things]

Users\List\[3 things]

As they all end up in the same namespace, the identifiers have to be unique for each thing.

Let's view this from the problem domain. The feature you are implementing is the presentation of user management. That is the logical grouping we want to convey - not the CRUD operations.

So let's group all user presenters in their own assembly:

UserManagementPresentation.csproj (default namespace Project.UI.Smart.Presenters)

UserAddPresenter.cs

UserAddCallback.cs

UserAddView.cs

UserListPresenter.cs

UserListCallback.cs

UserListView.cs

UserModifyPresenter.cs

UserModifyCallback.cs

UserModifyView.cs

This is a nice tight file list which, when referenced, will merge into the Presenters namespace along with any other assemblies written in the same pattern.

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 5:11 PM

@nick - you know i'm only jealous of your keyboard-jitsu!

@bryan -

i can't see that for a solution consisting of 100+ MVP triads. especially if you mean 1 project = 1 assembly (might be making a leap there). so go up a level from users and there's a bunch of other folders in a given assembly/project. each folder might have 0-8 sub folders. to me it's just easier to turn off the namespace provder for subsequent adds. not a big time savings, but everything counts (in large amounts).

so it may be a matter of personal preference. i will say i do your trick for spec assemblies (tests), e.g.

Xclaim.UI.Smart = Root NS, Xclaim.UI.Smart = Assembly

Xclaim.UI.Smart = Root NS, Xclaim.UI.Smart.Specs = Assembly

also... re: crud. it's a common pattern we see. we have a convention on our team where we'll break out by folder the add/modify/list. not quite crud, but close. it'd been helpful to settle on a way of breaking apart the ui logic in a quasi "resourceful" way. makes it easy to know where to go.

Bryan Watts wrote re: Folder != Namespace
on 12-18-2007 5:46 PM

With 100+ triads, you have 300+ things to keep in the same place, and that is going to get unwieldy no matter what technique you use to organize it. Because you have chosen "what it is" and not "where it's relevant" as the distinguishing factor, you have a potentially infinite list requiring ever-more-subtle distinctions to keep all the names unique.

I write a lot of APIs, and my organizational mantra is "group by function not form". Sure, you have all your presenters in one place, but what, in concrete terms, does that buy you?

The function of each triad is scoped to a particular kind of "thing". Why not have "Presenters" folder underneath the relevant "thing" folder? e.g.

\Project\UI\Admin\Users\Presenters

\Project\UI\Admin\Roles\Presenters

\Project\UI\Portal\Blog\Presenters

It makes more sense to me to have all things relevant to \Users scoped to that folder, rather than know "this kind of thing is here, and this kind of thing is over here, and this kind of this is back here", etc.

Is there some perceived benefit to having all presenters in the same place?

dave wrote re: Folder != Namespace
on 12-18-2007 6:02 PM

I can't see it - is it a ReSharper thing?  Or VS2008?  neither of which I have :(

Andy wrote re: Folder != Namespace
on 12-18-2007 6:10 PM

It's a ReSharper feature.

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 6:21 PM

@bryan - the benefit is: we know where to find our presenters. in the ui assembly we break things out like so:

Services/

Presenters/

Views/

Adapters/

Commands/

so not all of them are "resourceful" sometimes a presenter is a composite presenter that actually takes in a few things. presenter is an important concept for us, and we organize by our pattern language in this viewpoint to take advantage of the fact that, yes, sometimes things are resourceful but sometimes they represent a process, such as indexing and routing document images.

having them in the same place means you have a single place to go to find classes of that responsibility (again, as things don't break down into resources all the time). when they do break down into resources we have a folder convention for that, like i mentioned. my preference is to use a single studio project (per logical layer) and do any assembly partitioning we need to do in nant/msbuild.

grouping by presenter, to me, is grouping by function. it seems that grouping by "entity" would be more like grouping by form as grouping by entities implies the form of a larger information architecture / user experience design.

in this choice, i guess we disagree.

@dave - must be a R# thing. i have R# 3 and VS 2005 in the screenshot.

Bryan Watts wrote re: Folder != Namespace
on 12-18-2007 6:57 PM

We disagree in our definition of function. I am referring to the ultimate function of any specific class, not of the general system or any base class.

As such, I define it as "Presentation of user management", where presentation is the form and user management is the conceptual domain. Form + domain = function.

In your approach, you have to *know* that all presenters are in one location. That knowledge and location are proprietary to your solution. It's a convention, so probably a no-brainer for you. But, when someone new comes along, they must be explicitly told that. The discoverability is low, though *ostensibly* it's higher.

In my approach, presenters appear wherever they are relevant. Want to know what presenters are in effect for users? They live right next to _everything else_ that's user-related. If someone comes along in a vacuum, they are easily able to discover that users have relevant presenters.

It's a bigger design philosophy: I am more apt to have 10 kinds of things relating to users all in 1 place, than I am to have 10 different places in each of which 1 thing relevant to users appears.

Partition your code based on the business problem domain, *not* the coding problem domain.

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 7:36 PM

@bryan -

ok, i understand your position. i still disagree.

how is your approach any more/less proprietary than mine?

how is discoverability lower? for example,

"i want to control how user details are presented. ok, i guess i need to be dealing with presenters and views. well, i know it's the presentation logic so i know i want a presenter. i also know that we call presenters that control individual detail views something like NameOfThing_Detail_Presenter. Ok. CTRL+N "UDP". Now I'm in business."

sure there is, as knuth says, knowledge in the head, but the raw materials for that thought process are documented on our wiki and swirling around the conversation in our team room in the form of tacit knowledge, pair programming, etc.

aren't you boxing yourself into a very entity-oriented organization? what about process orientation?

when i think of a presenter it had better damn well be controlling a view, handling user gestures, etc. what a presenter does. we can start to think about that as a category of responsibility. we can think about this as what eric evans calls in DDD a "responsibility layer" (in a simple sense) and use this as a layer-within-layer approach for a medium to large system.

also, even if you partition across multiple assemblies aren't you boxing yourself, from a business concept standpoint, across a layered architecture? a user must go from database to model to services to controller to view? that's simply an untenable option for an application that needs to live forever and evolve.

and i certainly do partition my code based on the business. in services, for example, there is no organization like this. folder = service = logical grouping of operations = rpc style facade. in the model layer things directly model the business problem according to knowledge acquired and the ubiquitous language. to follow one organization scheme across all layers seems a brittle approach.

Bryan Watts wrote re: Folder != Namespace
on 12-18-2007 8:57 PM

There is a jump in your logic which I think hints at the differences in our perspective. When faced with

"I want to control how user details are presented."

you think

"ok, i guess i need to be dealing with presenters and views."

and I think

"ok, I guess I need to be dealing with users."

In your question, "user details" comes before "presenter". Presenter is an aspect of user, not vice versa. You can't have a presenter before you have something to present.

So, if I'm new to your system, I will most likely know about users because I'm asking about them. I might not know about presenters. So, if they are not bundled with users, discovery of presentation logic happens via trial and error or explicitly being told.

The logical issue is that definitions of presenters and their aggregation are 2 distinct concepts, but are tied together when they must reside in the same namespace.

Process orientation is a concern at the aggregate level. You achieve that via configuration, i.e. "now that I have these different presenters, located where they are most relevant, I shall notify some central component of their existence."

Dave Laribee wrote re: Folder != Namespace
on 12-18-2007 9:23 PM

well, yes, i expect developers to consider the impact of a story on all slices of the cake. in terms of changing the user model, those would be out there in front. same for the application service. the ui is a different contextual boundary with it's own requirements for presentation (not presenter) and user experience.

process orientation, while yes being an larger level concern, is _generally best_ achieved through model (not view/presenter) reuse. not thinking about process or designing ui for process, in my experience, is a recipe for disaster or - at very least - underwhelming software.

you most certainly can drive out the concept of the user from the MVP side up. we do it all the time to great effect. eventually, to fulfill a story / unit of work you'll need to have a user entity somewhere.

what do you think of the rails convention of separating model, controller, and view artifacts?

not to be rude (really), but your approach (while working for you) seems counter to just about every successful source tree i've ever seen/worked on.

Bryan Watts wrote re: Folder != Namespace
on 12-19-2007 1:24 AM

No worries.

The rails conventions are rooted in a scripting mentality, where all-encompassing directories make managing includes less painful, among other things.

It comes down to grouping artifacts by their roles in the mechanics of the web solution versus their roles in the business problem. The structure of model/view/controller isn't going to change; you're resigned to stuffing more and more things in the same boxes, which doesn't scale. This very post is about a circumvention of established convention, via a 3rd party tool, combined with tacit knowledge, just to make it manageable.

Separating things out by "what they are" is a more industrial, brute-force approach, whereas "put things where they are relevant" is a more organic approach that scales with the problem domain.

Dave Laribee wrote re: Folder != Namespace
on 12-19-2007 1:42 AM

do you have a blog?

just 'cause i'm not convinced now doesn't mean I wouldn't love to see a longer treatment!

» Daily Bits - December 19, 2007 Alvin Ashcraft’s Daily Geek Bits: Daily links plus random ramblings about development, gadgets and raising rugrats. wrote » Daily Bits - December 19, 2007 Alvin Ashcraft’s Daily Geek Bits: Daily links plus random ramblings about development, gadgets and raising rugrats.
on 12-19-2007 10:19 AM

Pingback from  » Daily Bits - December 19, 2007 Alvin Ashcraft’s Daily Geek Bits: Daily links plus random ramblings about development, gadgets and raising rugrats.

Bryan Watts wrote re: Folder != Namespace
on 12-19-2007 10:34 AM

I just created my blog recently, but haven't posted anything yet. Perhaps I have my first topic: Function = Form + Business Problem. I'll be sure to pingback once I write it up.

In the meantime, there is an analogy which may help orient you to my thinking. What we have described is a composition to the solution of presentation of user management: several components of different types which, when used in conjunction, produce the desired result.

This sounds much like the web paradigm of .aspx, .css, and .js files, which "team up" to produce the desired page. Let's explore each of our organizational schemas by applying them to this similar problem.

In the "what they are" strategy, we're segregating by component type, so we'll make \CSS\, \ClientScript\, and \Pages\ folders. Already this sheds some light: does it really make sense to have a "Pages" folder? Aren't pages better organized by what they do, not what they are? Aren't they analagous to your presenters?

Once we have the structure, let's populate it with 100 pages (triads). To create a triad, I must put things in 3 separate places. To delete a triad, I must also visit those same 3 places - hope I don't forget one!

Now, with 3 folders and 100 files per folder, I can easily find where all my CSS is - but, finding that one exact file I'm seeking proves a bit harder. This can be alleviated by decoupling folders from namespaces, but now I have more folders to sift through, another arbitrary organizational line of thinking to follow, and that pesky ingrained namespace convention that makes understanding all of this that much harder!

In the "where they are relevant" strategy, we'll have a single top-level folder, \Users\, which contains all relevant user pages, CSS, and client-script. You don't have to go anywhere to find all relevant components, and if you remove the "User" concept by deleting the folder, there is no danger of increasing code rot by leaving a file around. No tacit knowledge is required and you still get folder namespacing.

If I'm making a cake, I don't go to 1 grocery store for milk and another for eggs.

(I realize that .css files should be in a theme directory with .skin files. This was illustrative only, and the "where they are relevant" concept still applies: styling information isn't relevant to user page *structure*. Themes still group different component types under a common goal - you don't implement them in "App_Themes_CSS" and "App_Themes_Skins")

Bryan Watts wrote re: Folder != Namespace
on 12-19-2007 10:43 AM

I also forgot to mention that a structure of

Services/

Presenters/

Views/

Adapters/

Commands/

That only only tells me the kinds of things in the web solution, not what they *relate* to. I'm a web developer. I know there will be commands, adapters, presenters, etc., in a web solution, and I know how to handle them when encountered. Most likely they will have a suffix that lets me know what they are.

I want to know what *problem* is solved, and I can't get a good gut-feel idea without arbitrarily picking code to read.

Dave Laribee wrote re: Folder != Namespace
on 12-19-2007 11:09 AM

@bryan -

> If I'm making a cake, I don't go to 1 grocery store for milk and another for eggs.

no, but you do go to one grocery story with multiple aisles ;)

not to focus on the wrong part of the conversation.

i do hope that you post a sample project layout with a description of your method. please send it to me and we'll continue the conversation at the blog level!

Bryan Watts wrote re: Folder != Namespace
on 12-19-2007 11:16 AM

> no, but you do go to one grocery story with multiple aisles ;)

I tripped up on the analogy. It should have been phrased as:

"If I'm making a cake, I don't go to the milk store and the egg store." :-)

I'll post something over the holidays.

Trumpi's blog wrote Our daily link (2007-12-20)
on 12-20-2007 4:42 PM

Did all my Christmas shopping today. The shops were really busy. And now I don't feel like commenting

Colin Jack wrote re: Folder != Namespace
on 12-24-2007 7:05 AM

Interesting discussion, as always the best bit about any blog entry is in the comments!

@Bryan

Personally I can see a lot of what your saying, but I'm looking forward to the example. I'm also quite comfortable with the approach David uses though and to me the main thing about folder structures is that you'll never come up with one that everyone is happy with or that is right for every situation.

@Dave Laribee

When you say "my preference is to use a single studio project (per logical layer)" do you mean you'd only have one domain project? If so do your subdivide your domain (CRM/Ordering/Finance) by namespace?

Dave Laribee wrote re: Folder != Namespace
on 12-24-2007 2:30 PM

@Colin - Yes. Some (not entirely strict) combination of namespaces, facades, and anti-corruption layer are how I implement the "module" pattern from DDD. We have a number of models in various projects. Our document management product has three models: Metadata, Workflow, and Security. We use the aforementioned technique. For larger problems I'm looking at Udi's NServiceBus as a cornerstone for a context mapping between many models. In this case (where models are connected by a bus) I'd peel the models off into separate projects.

Colin Jack wrote re: Folder != Namespace
on 12-29-2007 7:24 AM

@David

Interesting. We could certainly have used namespaces and I know some people recommend that but I don't think they are the most natural way to handle depdendencies. Facades I can see, anti-corruption layers though are not always appropriate when you are talking about multiple modules within a single bounded context.

Our approach so far has just been to have seperate domain projects e.g. Ordering/Crm/Finance. We aggressively look at coupling between these domain modules. So my question is whether when you just use one project do you really get the main advantages of modules in terms of managing complexity.

Seems interesting though, you thought of blogging about it? :)

Sam Gentile wrote Advanced WCF Code Camp Slides and Code
on 01-12-2008 8:07 PM

Thank you Code Campers! I had 120 out of 400 of you (ASP.NET MVC was at same time) and you were a great

Terry Thibodeau's Blog wrote Testing NHibernate object mappings in isolation
on 02-21-2008 3:16 PM

The other day, I found myself creating a bunch of new NHibernate object mapping files for the project

gerson wrote re: Folder != Namespace
on 03-11-2008 6:32 PM

I create all of the code in my computer plantform very good character everthing is coming in my computer

ALPHA COMPUTER POWER DATABASE

http://agile.codebetter.com/blogs/david_laribee/archive/2007/12/18/folder-namespace.aspx wrote http://agile.codebetter.com/blogs/david_laribee/archive/2007/12/18/folder-namespace.aspx
on 03-24-2008 3:56 AM
Sam Gentile's Blog wrote Advanced WCF Code Camp Slides and Code
on 12-02-2008 6:47 PM

Thank you Code Campers! I had 120 out of 400 of you (ASP.NET MVC was at same time) and you were a great group. I had a great time with a new talk. Remember - just say no to RPC and Request/Reply - embrace the diversity of Asynchronous Messaging and Event

tower defense wrote re: Folder != Namespace
on 05-09-2009 4:20 AM

I tripped up on the analogy. It should have been phrased as: "If I'm making a cake, I don't go to the milk store and the egg store.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?