I am pleased to announce that after a slightly unexpected delay, the next installment in the Autumn Of Agile screencast series is now available for immediate download from the main site. I had a bit of trouble trying to determine the best way to compose this installment given that there is both a) a lot of material in there and b) a stated goal of keeping each installment at about 1.5 hours in maximum length.
Oops — I went over TIME again
I eventually just gave up on the planned 1.5 hour maximum length and recorded this whole thing as one single installment and even though it clocks in at a brand new record for me of 2:42 I still didn’t manage to cover everything that I had hoped for.
As you can tell by this, I continue to struggle with the best way to present this material and have a growing concern that a 2.5+ hour screencast is just entirely too long for anyone to really sit through (even if the material is useful/helpful/valuable) so I would welcome feedback from viewers on this point.
I guess you could argue that since this installment was two weeks in the making rather than the planned 1-week for each that I did manage to keep it under the hypothetical 3-hour length that 2-weeks should have given me, but….
…The struggle between “keep length to 1.5 hours” and “show everything so that viewers can properly follow along” continues! Again, I would welcome input on this from viewers.
Good News: A Wide Array of Topics
Since I did take the whole 2:42 for this installment, the good news is that I managed to cover a pretty wide array of topics in here including…
- Intro to Inversion-of-Control and why we care about it
- Overview of Rhino Tools and its suite of capabilities
- Configuring Rhino Tools to leverage Repository<T> to effortlessly wire up support for NHibernate data access methods
- Configuring Rhino Tools IoC container to support its UnitOfWork implementation in our persistence unit tests
- Setting up our persistence unit tests to properly manage database state
- Refactoring our unit tests to place common (annoying) code in a common base fixture class
- Creating our first ASP.NET MVC project
- Wiring up the Rhino Tools infrastructure into the ASP.NET MVC project so its UnitOfWork httpmodule can properly manage NHibernate ISession lifecycle for us
- Providing our own ControllerFactory for ASP.NET MVC that properly leverages the Rhino Tools IoC container wrapper atop Castle Windsor
Happy viewing and I really hope to be able to revert to a 1.5-hour length format for the subsequent installments in the series.
Congratulations for the screen cast and for your new membership. Very very good job.
PS: the url to the http://www.autumnofagile.net/ in my rss is wrong! Can you please check?
Wow… that’s a lot for my poor little brain to process. However, I wouldn’t want to compromise on the level of detail you provide, so my vote is for – by all means try to keep length to 1.5 hours, but if it can’t be done in that time then it can’t be done, let the music play on.
I’ve got a pause button, if my brain starts throbbing or I need to take a break / get a coffee, then I’ll pause it and come back when I’m ready.
I agree 2:42 hours is a long time to sit paying attention to someone but Casino Royale is about that long and you have to pay attention to the twists and turns.
Sorry — typo in the link. Noted and fixed already.
Thanks for the heads-up.
I will try for fewer plot-twists than Casino Royale 😀
Great! I know what I am going to do tonight: watch your screen cast in 1.4x speed in MediaPlayer 😉
Keep up the excellent work!!!
P.S.: could you please provide Microdesk.Domain.Foundation with the source code of this installment.
Once again, a tremendous wealth of information. I have no qualms about sitting through a 2hr+ screencast as long as it doesn’t have a lot of worthless fluff. Your screencasts are always worth the time; please don’t compromise merely to make them shorter.
Great job and a sincere “thank you” for the time and effort you have put into these. As with your Summer of NHib vids, these are invaluable.
Keep up the great work! (please)
I don’t mind the additional length of the web casts – the content is outstanding, so it’s just more of good thing. Great job, by the way.
Why do you decide to use asp.net mvc over castle monorail. Just curious, because asp.net mvc is still in beta stage.
Exactly, the length over 2 hours doesn’t matter, especially when the episode is full of great content! Keep up great work!
See my comment #14 on this post for some of my reasoning behind my choice…
Steve, come on… You gave us an extra hour of extraordinary content, and you feel bad about it 🙂
While waiting for next installment I feel like a fan girl (groupie is too explicit term, according to Wikipedia :), waiting for her favorite pop band to perform. Just bring them on.
And of course, congrats to you and Davy for joining the team!
My only fear is that nobody will want to watch a 2.75-hour screencast and the length will be a turn-off (making my efforts less valuable to others) and an impediment to people finding value in the content.
So long as people tell me that they are ok with the length, I won’t sweat it as much (which seems to be the general thought from the comments).
You’re outstanding! Congrats for being a new contributor to the NHibernate team. http://unhandled-exceptions.com/blog/wp-includes/images/smilies/icon_smile.gif
I don’t mind about the length of the video. I do appreciate your hardwork.
More power and keep up the outstanding work.
Thanks a million.
I too, just wanted to let you know that i was able to sit through the complete episode in 1 go. The wealth of information that you give us, combined with allowing us to look over your shoulder while your creative juices are flowing freely, makes me look forward to each installment with great anticipation !
Keep up the good work, you are definitely on the right path.
+1 for 2.5+ hour screencast..
What, you actually LIKED that point in the middle where I seem to lose track of how to best test that I can save an updated Employuee object, try to compose the test one way and then give up and try another –?
Not one of my finer moments… 😀
Thanks and I was anxiously waiting for screen cast and finally I have it now 🙂
Here is what I think,
you should really not worried about the length of the video if the viewer gets tired watching or sleep in the middle of screen cast guess what the user will play again 😉
Please feel free to have whatever it takes you in terms of length.
Looking forward for the next screen cast….
OK, I will take it on faith then that the length is acceptable based on the feedback I see here (although I cannot help but at least CONSIDER that this is a self-reinforcing feedback loop where those who HATED the longer length just clicked STOP, deleted the download, and never posted their feedback here~! 😀 )
Thank you again. I, for one am very grateful that you are willing to spend the time to give so much for the Agile and NH communities. If that means the screen casts need to be longer to ensure that quality of the information is kept intact then so be it.
Like many before, I make ample use of the various functions of media player (Pause, Seek, Etc) to get the most out of the sessions. I really enjoy the warts and all approach. It’s nice to know that the teacher is one of us, a person that struggles sometimes with the best way how to get something done. Personally I think it is refreshing and encouraging to think that I am not the only one.
Keep up the great work. Looking forward to the next one.
I don’t have any problem with the screen casts being that long! Keep them coming.
One thing that I’m wondering about is documentation.
How would you put that to use in a Agile project? Documentation doesn’t have highest priority, but in order to work in a team you’d still need some kind of documentation. (No 900 pages, but maybe 10 pages of self describing diagrams?)
Can you give us some insight on this? What tools, etc..
Documentation (or my lack of talking about it in the SkillPortal example project) is a great point.
In my case, I am (of course) a single dev on the project so all my docs and design ideas can be in my head since I don’t have to share them with anyone else. But the topic of ‘what level of docs are needed’ in Agile is recurring debate among Agilists and is (I think) an area where new Agile adopters tend to go most wrong and assume that the line in the Agile Manifesto about ‘favoring working code over documentation’ should mean “if the code is working, I will need no documentation of it”. The line in the Manifesto was (IMHO) about system documentation for code that has been written already, NOT design documentation for code that hasn’t yet.
The premise behind docs in Agile is (IMHO) the same premise as that behind how you write code: JIT design. Just as we don’t want to make decisions in code before we absolutely have to in our iterations, we similarly don’t want to document anything until we absolutely have to. BDUF (Big-Design-Up-Front), HRD (Huge-Requirements-Document), and others are to be avoided at all costs of course.
That isn’t to say that there is no documentation. You will note in the screencasts for example that I spend considerable time listing req’ments, creating user stories, and defining tasks against them for planning purposes. These steps (even if executed sometimes with software like TargetProcess and other times with index cards on a bulletin board) are essential to any project team ensuring there is general agreement about the overall project roadmap.
One part of the typical documentation that is missing from the Autumn Of Agile screencasts is the high-level system architecture diagram that the team would also have to agree on before much non-spike coding went on. The team has to agree (at a high level) about the structure, flow, components, and dependencies the overall system will provide before anyone can ‘just start coding’.
I know this flies in the face of the XP purists, but its true for anything other than the most trivial of projects. What we *don’t* have to do is construct an entire suite of UML diagrams covering class relationships, sequence diagrams, inheritance hierarchies, and the rest of what usually evidences the BDUF approach applied to the technical aspects of the project. But we have to agree on the technical roadmap in broad strokes else we are likley to be working at significant cross-purposes without realizing it (until the end of the iteration and we try to integrate with each other only to find all kind of system architecture conflicts between our work).
My preferred tool for this is the whiteboard 😀 but its not always the case that the entire team is co-located or that there is a dedicated whiteboard/war-room for the project that we can just rely upon for this. In these cases, the usual tools that I tend to prefer for this are digramming tools like the FreeMind mind-mapper tool demonstrated in the Iteration -1 installments or Microsoft’s OneNote. I find that actual UML tools (like either VISIO, Sparx Enterprise Architect, or anything else UML-centric) is too likely to ask me to ‘get into the weeds’ too soon just to satisfy its UML-based constraints (which I’m not ready to do when we are working at this higher level).
Your choice of tools will need to satisfy your own needs, but IMO the proper focus of the tool needs to be on DIAGRAMMING (in pictures) rather than DOCUMENTING (in words) the overal design of the project at a high level. The combination of the diagrams at this level and the documentation that the features, user stories, and tasks provide is usually most of what is needed to ensure that there are adequate artifacts that the team can use as the centerpoint of their discussion of issues as the project progresses.
Hope this helps,
love it, 1 hour or 2.5 (even better). Thank you for this!
i just finish watching screen cast and i think i need to learn more about Rhino and some of knowledge i could not able to grasp like when you talk on MVC controller in the global but i guess i have to wait and see the coming screen cast.
oh i just wanted let you know that, the reason you could not able to copy file to asp.net mvc project is because you were on Run mode so your “paste” and “include in project” was disabled and i know it was 12:20am so i understand 🙂
thanks for your time.
Thanks for the feedback on my troubles trying to paste the hibernate.cf.xml file into the web project — I thought I was starting to lose my mind there for a minute. As you say, it was 12:20am so I’m allowed a little confusion, I guess 😀
As for being able to follow along on exactly what I was up to in the global.asax.cs file to wire up Rhino Tools into the MVC ControllerFactory infrastructure, my reasoning will (hopefully) become clear in the next screencast where we will start to tie in the Rhino Tools IoC container and type registrations to the design of our own MVC IController implementations (we will be leveraging this to ensure that our Controllers are instantiated with the needed dependencies like Repositories, etc).
This is (unfortunately) one of the challenges that I am facing with this series in that unlike the Summer of NHibernate installments where the stated goal was to do a complete step-by-step tutorial where I was proceding from the assumption that people had no prior exposure to NHibernate, in this series I am not necessarily going to be able to take the time to completely explain every nuance of everything that I’m doing (else the series would take about 2 years~!) but am instead relying heavily on the vast array of other sources of info out there on the web for people to be able to dig deeper into specifics on any one of the technologies that I am leveraging in this series.
For some research on what I was trying to accomplish with all of that ControllerFactory stuff, I recommend you take a look at this installment from DimeCasts.NET on wiring up StructureMap (another .NET IoC container) into the ASP.NET MVC ControllerFactory process…
Although that 10-minute screencast is about using a completely different IoC container than I prefer, the principles are the same and they go into a bit more detail on how/why they are doing what they are doing there.
Hope this helps, and I hope it all becomes more clear in the next installment where we (finally) get to build on the infrastructure that we have been assembling and wiring up in the prior installments.
Thanks Steve and i will look the dimecasts
i’m kinda wondering if you are planning to use SPROCs? (select, insert, delete) it will be nice if you can use in SkillPortal project….
I think the majority of folks are stuck using SPROCs
As I’m sure you are aware, I’m not really a big fan of sprocs for just about anything if I can avoid it.
Most of the seeming benefits of sprocs have been slowly whittled away over the past 10-15 years to the point where the few remaining benefits are largely eclipsed by their negatives and so given a choice, I will nearly-always choose against sprocs as part of my solutions.
And in the SkillPortal project, I’m in charge so I have the choice 😀
I agree that many are ‘stuck’ using stored procs in many situations, but the process I’m showing in this screencast wouldn’t be appreciably different even if sprocs were used — the differences would be in how I would construct the mappings for NHibernate when it came time to interact with the database.
But from a code standpoint, my process would likely be largely the same as you are seeing in these screencasts (e.g., I would still argue STRONGLY for an abstraction layer between my objects and my persistence interaction that would look mostly like what you are seeing here). Its certain that the .hbm.xml files would look considerably different and its even possible that the internals of some of the methods in my repositories might be different, but the public surface area of the API for my repositories would really look the same (e.g., methods like GetAllSkills(…) would still be there all the same).
i wish that i have luxury to use inline sql but in my org dba’s are death aginst using any inline sql statements and plus the db is so complicated its next to impossible in my situation.and besides we use sprocs and functions.
i have seen all the nhibernate series and also i’m aware that you did demonstrate how to use sprocs mainly insert/update/delete.
one small request: is there a way you can have screen cast for 10-15 minutes demonstrate how to use SPROCs (using SELECT) ?
i hope i’m not asking too much 🙂
For some detailed step-by-step on this, I cannot do a detailed screencast, but there are other excellent resources out there that attempt to document this for you.
For just a couple, I can point you to…
Populating Entities From Stored Procedures With NHibernate
Populating Entities With Associations From Stored Procedures With NHibernate
Both of these are from Davy Brion, the newer member of the NHibernate committers team that recently stole my right to that title.
For step-by-step treatment of many specifics on NHibernate, Davy’s blog is a great source of tutorial-style info on how to use some of the vaguarities of the NHibernate framework.
Best of luck and I hope this helps point you in the right direction.
thanks a lot, appreciate your help.
i have a question:
what is your views on LINQ2SQL? i mean instead of using NHibernate can/should use LINQ2SQL ?
shed some light please.
Enough people have now asked for some input from me on this general topic (L2S, EF, NH, etc., etc., etc.) and how one might approach choosing one of these over the other that I am now breaking down and doing a blog post that wraps up my overall thougths, impressions, recommendations, and opinions about all of this in one place.
So, my answer is….COMING SOON 🙂
[…] record for length: 3 hours and 17 minutes! I know that in comments rec’d to this prior post, viewers indicated that longer wasn’t necessarily an issue (so long as there was good content […]
I have a problem and I do not know how to solve it. I am trying to rebuild “Autumn of Agile: Iteration 1 Part B” with Rhino Commons latest build. I downloaded the source code from the repository >> then build using the *.bat file >> take the *.dll files from the build directory. But NHibernate has a breaking change with the proxy factory. For that reason I added this property to the configuration file:
But I still get the error:
failed: Unable to load type ‘NHibernate.ProxyGenerators.CastleDynamicProxy.ProxyFactoryFactory, NHibernate.ProxyGenerators.CastleDynamicProxy’ during configuration of proxy factory class.
I think I have to add NHibernate.ByteCode.Castle.dll, but is there some work around to fix this because the RhinoCommons do not contains such a file?
The NHibernate.ByteCode.Castle.dll ass’y isn’t part of Rhino.Commons, its part of the NHibernate distro.
Your stuck in OSS dependency hell as pointed out in this post: http://unhandled-exceptions.com/blog/index.php/2008/12/08/horn-project-removing-oss-cross-dependency-pains/
Its a long story what’s going on here, but this was part of an intentional move to break NH’s concrete dependency on the Castle Dynamic proxy specifically to help alleviate exactly the issue that you’re pointing out: a change in the trunk of one OSS project can cause some serious downstream dependency issues.
There are two basic solutions to your issue:
1) the easy one: use the ver of NH that is available in the SharedLib folder of the Rhino.Commons SVN repository; this one is GUARANTEED to work since its the one that the present Rhino.Commons trunk is built/tested against
2) post to the Rhino.Tools google group and ask what the latest ver of NH that Rhino.Tools is presently tested against
Its near-certain that if you grab NH, Castle, and Rhino.Tools each from their respective trunks that you will run into a never-ending death-spiral of interdependencies and breaking changes from which you may indeed emerge victorious but only after quite some effort on your part with (often) dubious value for yourself.
Bottom line: unless you are in need of a *specific* feature that has been introduced into the trunk of one of Rhino.Tools’ depenecies (e.g., Castle or NH) you are best-off *not* trying to do what you are trying to do here and patiently waiting unitl the ‘top’ of the dependency hierarchy here (Rhino.Tools in this case) comes along to support a later build of either Castle or NH.
I know this isn’t what most people want to hear, but its my own experience with this series of interdependent libs; having the latest-greatest-shinyest-newest version of all of these just to say you have them is often a painful journey with little reward for your efforts 🙁
Hope this helps (some!)
10x Steve, but I think you misunderstood me. I did not get latest version of NHibernate or Castle. I just go and download the source of rhino.commons because this is the only way I can get it. And then build with the *.bat file. Ok, forget about this. Is there any other way to get rhino commons? How you get the rhino.commons dlls which you use for AutumnOfAgile?
I think I should go to rhino’s blog/forum!
PS: What is going on with the screen casts?
Have a nice day!
Ah, you are right — I (completely) misunderstood. As per the ‘How to build.txt’ file in the rhino-tools\trunk folder, here’s how I do it…
1) Go to SVN repos and GET everything under Rhino-Tools\
2) open a command-prompt, and navigate to rhino-tools\trunk as your current folder
3) type ‘sharedlibs\tools\nant\nant -D:common.testrunner.enabled=false’ (no single quotes, of course!) and hit enter
4) results will be in rhino-tools\trunk\build\net-3.5\debug when the build completes
EVERYTHING in that folder (the NH-related DLLs, the CASTLE-related DDLs, etc., etc.) is all correlated to be the right version for the build of Rhino.Tools that you will have succssfully just built.
HTH and let me know how you make out with it~!
10x Steve. I will try this later. Can you tell me what “product” is created under the \\root\build\ directory when I start the *.bat file from the root directory?
Have a nice day!
Hi again. I did as you told me. The NHibernate.ByteCode.Castle.dll was there and everything is running. Now, I must consider your post about OSS dependency hell 🙂
failed: The following types may not be used as proxies:
method get_LastUpdatedDateTime should be ‘public/protected virtual’ or ‘protected internal virtual’
method get_LastUpdatedBy should be ‘public/protected virtual’ or ‘protected internal virtual’
method get_LastUpdatedDateTime should be ‘public/protected virtual’ or ‘protected internal virtual’
method get_LastUpdatedBy should be ‘public/protected virtual’ or ‘protected internal virtual’
Message: The following types may not be used as proxies:
NMX.Dictionary.DomainModel.Project: method get_LastUpdatedDateTime should be ‘public/protected virtual’ or ‘protected internal virtual’
NMX.Dictionary.DomainModel.Project: method get_LastUpdatedBy should be ‘public/protected virtual’ or ‘protected internal virtual’
NMX.Dictionary.DomainModel.Word: method get_LastUpdatedDateTime should be ‘public/protected virtual’ or ‘protected internal virtual’
NMX.Dictionary.DomainModel.Word: method get_LastUpdatedBy should be ‘public/protected virtual’ or ‘protected internal virtual’
at Rhino.Commons.NHibernateUnitOfWorkFactory.CreateSession(IDbConnection maybeUserProvidedConnection)
at Rhino.Commons.NHibernateUnitOfWorkFactory.Create(IDbConnection maybeUserProvidedConnection, IUnitOfWorkImplementor previous)
at Rhino.Commons.UnitOfWork.Start(IDbConnection connection, UnitOfWorkNestingOptions nestingOptions)
Glad to have helped. As for you remainder exception stack there, try the Microdesk.Domain.Foundation.dll found in the last available code download and that issue is (should be) resolved in the binary for that found in the /lib/ folder of the download ZIP.
I screwed up and failed to define the base class’ props as virtual until later — my oversight!
Thank you very much for the help Steve!!!
There is one open question about Microdesk.Domain.Foundation. Before 3-4 months you said that there is a little hope your blog subscribers and all other people to have the source of this lib. What is the status?
And let the force be with you!
This will likely be happening within the next month at the latest, but as part of the process the namespaces will be changing to remove any reference to my employer.
This will be true of the Domain Foundation library as well as the Unit Test Utility.
Stay tuned for more info~!
Good to hear that. When this becomes reality I want to add a support for compact database in UnitTestUtility library.
Technically, the unit test utility supports only DBs that the underlying NDbUnit core library provides support for so you could actually develop a patch RIGHT NOW for NDbUnit and I could apply that to the trunk and then extend the unit test utility to leverage this new DB type quite easily.
The Unit Test Utility’s list of supported DBs is just an abstraction-wrapper around the NDbUnit support for diff DBs.
love the casts and very thankful for effort. How we doing with the microdesk.domain.foundation classes? perhaps even a stripped down version just to highlight the db load & save functionality?
love your work
Thanks for the feedback; glad you are enjoying the content and finding value in it.
Re: the Microdesk.Domain.Foundation classes, see this post for an update (I’ve gone OSS with the code now)…
Right. I have found great value in the series, but I have some queries after running through the code.
Each of the repositories are doing pretty much the same functions i.e. save, get, find etc.
Yet we are creating a repository every time and using the base class to execute the function. This requires manually adding the repository and interfaces for entities which may not ever require any additional methods to persist data. This smells of a DRY (Don’t Repeat Yourself) violation.
Surely we could register a generic repository with windsor and use generics to pass in the entity. Something like:
public class GenericRepository : Rhino.Commons.NHRepository
and then have access to it via:
IRepository repository = IoC.Container.Resolve<IRepository>();
My issue seems to be how to handle the UnitOfWork??
I would rather not have to create a repository for every entity and would rather create a specific repository for an entity that requires extended methods.
So, is there a workaround to handle the UnitOfWork? I am sure this is a common concern.
With regards to my previous post, seems the “T” has been escaped when posting the code on this site, but the generic type will be passed into the GenericRepository””
“public class GenericRepository : Rhino.Commons.NHRepository
Thanks for the question(s).
We’re creating a repository for each domain entity because long-term we know we will need to have repository methods that are more robust than the CRUD we are starting with. The (example) signature of…
public class CustomerRepository : ICustomerRepository, NHRepository< Customer >
…is like that because I want to have a repository that will eventually evolve to handle just customers *in a domain-centric manner*.
Consumers of this will take a dependency only on the ICustomerRepository abstraction which will expose customer-centric methods only (e.g., .SaveCustomer(Customer) rather than .Save(T). The implementation will use the generically-defined methods of the base class to get its work done under the covers, enabling me to leverage the power of the base class without exposing the 100s of methods it offers as being part of the actual repoitory’s implementation (ICustomerRepository won’t expose the CRUD-centric methods of the NHRepository< T > base class so consumers won’t be aware/bothered by them).
Essentially, its this: if you just do…
public class Repostitory< T > : NHRepository< T >
…then you end up with a HUGE surface area for your repositories that offer up all kinds of CRUD-centric methods that aren’t expressed in domain terms, slowly leading to what I call ‘API pollution’ where your repository is just too API-rich for anyone to know how to consume/interact with without some kind of giant API reference guide being provided to them.
One of the big things that can (often) be hard to get your head around in Domain Driven Design is that even though the ‘role’ of the repository is to provide ‘persistence services’ for your domain, its also got the role of *abstracting* persistence from the rest of your domain and that (usually) means not just wrapping CRUD methods in a repository object but also expressing the persitence of domain objects in domain terms.
As a concrete example of this, consider the following two methods, each of which MIGHT result in the same action, deleting a customer from the system:
Both might (in the end) result in the customer being deleted, but the first one is expressed in terms the DBA will understand and the second one is expressed in terms your domain experts will (hopefully) understand.
In fact, CustomerRepository.RetireCustomer(Customer) might even just flag the customer as ‘inactive’ in the system and *update* the record instead of even performing an actual delete, but the point is that you wouldn’t actually have to CARE about that if you called CustomerRepository.RetireCustomer(Customer).
I hope this helps clarify where I’m coming from on this; I can agree with you that there may well be a YAGNI issue creeping in here, but my own personal experience has taught me that eventually IAGNA (I Am Gonna Need It) and so I’m proactively adding it before its immediately obvious that I will be requiring it.
Thanks again for the comments~!