Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
641 lines (527 sloc) 51.9 KB
S#arp Architecture 1.0 RTM
New and exciting in this release:
* Compatible with ASP.NET MVC 1.0
* All upgraded dependencies including NHibernate 2.1 CR 1
* We now have a community site at, still a work in progress (a flippin' ginormous thank you to Kyle Baley for setting this up)
* S#arp Architecture documentation may now be found at, still a work in progress (a huge thanks to Joe Lowrance for migrating the docs)
* Strongly typed action link for areas (SharpArch.Web.Areas.ActionLinkForAreas<> and BuildUrlFromExpressionForAreas<> - thanks Brad Buhrkuhl!)
* Fluent NHibernate now using configuration classes
* (Re)Introduced support for IIS 7 integrated mode
* Support for WCF has been added as SharpArch.Wcf for server support and SharpArch.WcfClient.Castle for auto-closing of the connection on the client (thanks Frank Laub!)
* SharpModelBinder has been introduced for much better form binding, including support for all association types; e.g., one-to-one, one-to-many, and many-to-one Entity associations
* Support for multiple databases outside of WCF communications (thanks Russell Thatcher, David Longnecker, James Broome and Howard van Rooijen for suggestions and input!)
Assembly Dependencies:
* ASP.NET MVC 1.0 Futures
* Castle Windsor 2.0
* Fluent NHibernate 0.1 (rev 539) built against NHibernate 2.1 CR 1
* jQuery 1.3.2
* Json.NET 3.5 Beta 4
* log4net
* Microsoft.Practices.ServiceLocation 1.0 (aka, "Common Service Locator")
* MvcContrib for MVC 1.0 (rev 959)
* NHibernate (2.1 CR 1)
* NHibernate.Linq 1.0 (rev 935)
* NHibernate.Validator (rev 935)
* NUnit (Installer in /tools)
* Rhino.Mocks
* System.Data.SQLite.DLL
* T4 Toolbox (Installer in /tools)
Required Upgrade Steps
Upgrading to S#arp Architecture 1.0 RTM from RC 2 requires a few steps to accommodate upgraded dependencies (steps also reflected in the Northwind sample project and VS generated projects). For reference, each of the following steps is prefixed with the dependency that that the upgrade step is associated with:
#) ASP.NET MVC: If you have any previous versions of ASP.NET MVC installed, you must uninstall them and optionally may install ASP.NET MVC 1.0
#) NUnit: Install NUnit 2.5 using the installer found within /tools (optionally uninstalling previous versions)
#) NUnit: Drop any usings of "using NUnit.Framework.SyntaxHelpers;" - this namespace no longer exists and has been merged into the NUnit.Framework namespace
#) NUnit: Change any use of ExpectedException attributes to use Assert.Throws instead; see for details
#) T4 Toolbox: Uninstall any previous version of T4 Toolbox and install T4 Toolbox (installer found in /tools)
#) T4 Toolbox: Replace your version of CrudScaffolding/ and CrudScaffolding/Templates/ with updated versions from
#) SharpArch: To easily update all the assembly references in your existing project, create a new project using the S#arp Architecture VS project template and copy the assemblies from /lib and /tools/lib to your project's respective folders (You could also copy them from the trunk's /bin folder, but using a generated project is simpler.)
#) SharpArch: Within YourProject.Tests/YourProject.Data/NHibernateMaps/MappingIntegrationTests.cs, add a reference to "using SharpArch.Testing.NHibernate;" to accommodate the move of RepositoryTestsHelper to the new namespace.
#) SharpArch: Upgrade YourProject.Tests/YourProject.Data/NHibernateMaps/MappingIntegrationTests.cs to accommodate the changes that were made to support multiple databases (if not done, you will likely have breaking unit tests). To do so, compare your MappingIntegrationTests.cs to the one at The necessary change is the introduction of the session factory key.
#) SharpArch: Within YourProject.Web/Global.asax.cs, migrate the call to NHibernateSession.Init() from the Global.asax.cs class' Init() method to its Application_BeginRequest() method using the following as an example:
#) Fluent NHibernate: Within Fluent NHibernate class maps and overrides, replace .WithKeyColumn("YourColumnName") with .KeyColumnNames.Add("YourColumnName")
#) Fluent NHibernate: If you're using Fluent NHibernate Auto Mapping, upgrade to Fluent NHibernate class conventions within YourProject.Data (You can look at the Northwind sample project for implementation examples but the Northwind DB is far from consistent and so there's an assortment of conventions and overrides in the Northwind sample project; accordingly, you'll have better luck having VS generate a S#arp Architecture project and then look at the internals of the generated project.):
*) Add a folder under /NHibernateMaps and add convention classes (see VS generated project for examples)
*) Within /NHibernateMaps/AutoPersistenceModelGenerator.cs, modify mappings setup to use new convention-per-class approach (see VS generated project for example)
*) See for further guidance
#) NHibernate: Within YourProject.Tests.YourProject.Data.NHibernateMaps.MappingIntegrationTests.cs, modify CanConfirmDatabaseMatchesMappings() to reflect the following:
public void CanConfirmDatabaseMatchesMappings() {
IDictionary<string, IClassMetadata> allClassMetadata =
foreach (KeyValuePair<string, IClassMetadata> entry in allClassMetadata) {
#) NHibernate: Within YourProject.Tests, add a reference to NHibernate.ByteCode.Castle.dll
#) NHibernate: Within YourProject.Web, add a reference to NHibernate.ByteCode.Castle.dll
#) Castle: Within YourProject.Tests/App.config, configure assemly redirects to reflect the following:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="Castle.Windsor" publicKeyToken="407dd0808d44fbdc" culture="neutral"/>
<bindingRedirect oldVersion="" newVersion=""/>
#) Castle: Within YourProject.Web/Web.config, configure assemly redirects to reflect the following:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="Castle.Windsor" publicKeyToken="407dd0808d44fbdc" culture="neutral"/>
<bindingRedirect oldVersion="" newVersion=""/>
#) NHibernate: Within YourProject.Tests/Hibernate.cfg.xml, add the following property:
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
#) NHibernate: Within YourProject.Web/NHibernate.config, add the following property:
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
Change Log
Solution Wide Changes:
* Updated all dependencies; only NHibernate and Fluent NHibernate had breaking changes, which were addresed in the upgrade steps above
Changes to SharpArch:
* Possibly BREAKING CHANGE (but not likely) ~ /DomainModel/BaseObject.cs: Changed HasSameObjectSignatureAs() to be public instead of protected since GetSignatureProperties() is also public and is a useful method to expose. This will cause a build error if you've overridden this method; to fix, simply change the visibility of the overridden method to public.
* /DomainModel/BaseObjectEqualityComparer.cs: Added this class to provide support for LINQ set operators, such as Intersect.
* /DomainModel/Entity.cs: Modified the GetHashCode to cache the hashcode calculation and to use the object's Id in the calculation for persistent objects. This was done because GetHashCode() was previously ignoring the Id property for Entities; therefore, two Entity instances which didn't have any domain signature properties were returning different hashcode values even if they had the same Id.
* Possibly BREAKING CHANGE (but not likely) ~ /NHibernate/DbContext.cs: Removed singleton behavior and added constructor parameter for session factory key to support multiple databases.
* /NHibernate/EntityDuplicateChecker.cs: Added factory key lookup for support of multiple databases.
* Possibly BREAKING CHANGE (but not likely) ~ /NHibernate/ISessionStorage.cs: Added FactoryKey property to support look-up for multiple database support and also moved this interface to its own file - I prefer having one class/interface per file.
* /NHibernate/NHibernateInitializer.cs: Added this class to assist with initializing the NHibernate session once and only once; this was introduced to help support running in IIS 7 integrated mode.
* Possibly BREAKING CHANGE (but not likely) ~ /NHibernate/NHibernateSession.cs: Changed SessionFactory and Storage to be Dictionary objects to support multiple databases; added plural named properties of each, accordingly. The singular version remain for backward compatibility and to make it easier to maintain a single database application.
* /NHibernate/NHibernateSession.cs: Within CreateSessionFactoryFor(), added ".ConventionDiscovery.AddAssembly(assembly);" calls after "m.FluentMappings.AddFromAssembly(assembly)" for altering non-automapped conventions. (Issue-101)
* /NHibernate/Repository.cs: Added factory key lookup for support of multiple databases. Also now passing factory key to DB context, accordingly.
* /NHibernate/SessionFactoryAttribute.cs: Introduced this attribute to be used on repositories to designate which session factory its associated with. It does not need to be used for single database scenarios or for your "default" database.
* /NHibernate/RepositoryTestsHelper.cs: Dropped the previously 4th parameter, a bool for formatting, to support the modified signature of NHibernate's SchemaExport.Execute()
* BREAKING CHANGE ~ /NHibernate/RepositoryTestsHelper.cs: Moved this helper class to SharpArch.Testing.NHibernate as it does not have dependencies on NUnit nor on MbUnit
* /CommonValidator/MvcValidationAdapter.cs: Added method overload to allow custom prefix to model state errors instead of the class name.
* /ModelBinder/EntityValueProviderResult.cs: Added support for Guid Ids
* Added this class library to support WCF. WCF does NOT currently support multiple databases.
* /Areas/LinkForAreasExtensions.cs: Added this class to provide the strongly typed ActionLinkForAreas<> and BuildUrlFromExpressionForAreas<>.
* /Areas/LinkForAreasExtensions.cs: Added this class to provide the strongly typed ActionLinkForAreas<> and BuildUrlFromExpressionForAreas<>. Accordingly, you can now replace hardcoded links to areas with Html.ActionLinkForAreas<>. You'll also likely want to add the following to your web.config's namespaces tag so that you don't have to import it for every ActionLinkForAreas: <add namespace="SharpArch.Web.Areas" />
* /CommonValidator/ValidatableModelBinder.cs: Marked this as obsolete in favor of using SharpModelBinder (referenced next)
* /ModelBinder/SharpModelBinder.cs: Added this model binder to replace the use of DefaultModelBinder (see documentation for details)
* /ModelBinder/EntityValueProviderResult.cs: Added this support class for SharpModelBinder (see documentation for details)
* /NHibernate/WebSessionStorage: Added overloaded constructor to accept a factory key to support multiple database sessions.
* /NHibernate/TransactionAttribute: Added option for passing in factory key to support multiple database. Also modified this transaction to rollback the transaction if a problem is encountered.
Changes to Northwind (all changes also made to VS project template and Employee CRUD pages):
* /Templates/Tests/Web/Controllers/ Modified CanEnsureEntityNameCreationIsValid() to account for fact that ModelState is not being modified during testing (it'll redirect due to invalid entity, but it won't show errors in the ModelState by default)
* /Templates/Web/Controllers/
- Added an EntityNameFormViewModel as a DTO between the controller and the entity form in both the Create/Edit (GET) action methods
- Modified Create/Edit (POST) to account for SharpModelBinder behavior
* /Templates/Web/Views/
- Replaced "id" hidden input id to be "EntityName.Id" to support SharpModelBinder
- Now inherits from ViewUserControl with a generic parameter of a form view model DTO to make it easier to send other items to the form such as lists for drop down boxes
- Changed hidden "id" input to be named "EntityName.Id" to support binding within SharpModelBinder
- Changed cancel button to use Html.BuildUrlFromExpression instead of hardcoding the back link
* /Templates/Web/Views/
- Got rid of redundant passing of ViewData to user control
- Added use of enum for looking for page message so that the ViewData index is strongly typed
* /Templates/Web/Views/ Now using Html.BuildUrlFromExpression for the URL behind the cancel button (more strongly typed)
* /Templates/Web/Views/ Wrapped all outputs within Server.HtmlEncode() to protect against JavaScript injection attacks
* /Templates/Web/Views/*.tt: Changed <h2> to <h1> at top of pages since they're primary page titles
* /Northwind.Data/NHibernateMaps/MappingIntegrationTests.cs: Introduced factory key to isolate the integration tests session factory from the other tests. Also set the SessionFactory and Storage to null before and after running the test for backwards compatibility reasons; in this way, existing tests that assume a single database don't have to be modified to account for the fact that a different session factory is being used by the MappingIntegrationTests class.
* /Global.asax.cs:
- Added SharpModelBinder as the default binder with "ModelBinders.Binders.DefaultBinder = new SharpModelBinder();"
- Moved initialization of NHibernate session to Application_BeginRequest with new NHibernateInitializer to support IIS 7 integrated mode
* /ControllerEnums.cs: Added this class to hold, at the very least, a strongly typed enum for global items added to ViewData.
S#arp Architecture RC 2 with ASP.NET MVC RC 2 and NHibernate 2.0.1
Version Acknowledgements:
* A huge thanks goes out to Kyle Baley and Simone Busoli who have been tremendously assistive to the #Arch community and the project during this recent push
New and exciting in this release:
* Compatible with ASP.NET MVC RC 2
* VS template project includes Fluent NHibernate auto persistence mapping by default
* Much more complete and extensible CRUD scaffolding generator - it's completely touch-up free for many scenarios
* Performance of unit tests using SQLite has been improved 20% (thanks Jay Oliver!)
* Added crazy cool anti-forgery voodoo magic to the CRUD scaffolding generator for creating, editing and deleting items (uh, thanks MVC team!)
* New empty class library, called YourProject.ApplicationServices, now gets added to VS generated projects
* S#arp Architecture now has a CI home with (thanks Kyle and Simone!)
Assembly Dependencies:
* ASP.NET MVC RC 1 Futures
* Castle 1.0 RC3 (rev 1038)
* Fluent NHibernate 0.1 (rev 381 - Does NOT include very recent Fluent NHibernate convention interfaces)
* jQuery 1.3.2
* Json.NET 3.5 Beta 2
* Microsoft.Practices.ServiceLocation 1.0 (aka, "Common Service Locator")
* MvcContrib for MVC RC (rev 903)
* NHibernate 2.0.1 GA
* NHibernate.Validator 1.2.0 (rev 809)
* NUnit 2.4.8
* Rhino.Mocks
* System.Data.SQLite.DLL
* T4 Toolbox
Upgrading to S#arp Architecture RC 2 from Beta (steps also reflected in the Northwind sample project):
#) If you have any previous versions of ASP.NET MVC installed, uninstall them and install ASP.NET MVC RC 2
#) Install NUnit 2.4.8
#) Upgrade T4 Toolbox to AND PATCH IT, following the instructions in the "Installing and Configuring Prerequisites" of the documentation
#) Update assembly dependencies from trunk/bin into your application's lib and /tools/lib folders
#) Modify using statements from "using NHibernate.Validator;" to "using NHibernate.Validator.Constraints;"
#) Change all reference to anyEntity.ID to anyEntity.Id.
#) Add the following assembly redirect to YourProject.Web/web.config and YourProject.Tests/App.config (since some dependencies will be looking for an older version of Iesi.Collections):
<assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
<bindingRedirect oldVersion="" newVersion=""/>
#) Within your Fluent NHibernate mapping files, rename .IsInverse() to .Inverse()
#) If you're using Fluent NHibernate auto mapping persistence, do the following account for the fact that you can no longer inherit from AutoMap:
1) For each class that inherits from AutoMap, remove the AutoMap inheritance and implement IAutoMappingOverride<YourEntity> instead.
2) Move the contents of the constructor, which sets up the overrides, to the body of the following, prefixing each line with "map.":
public void Override(AutoMap<YourEntity> mapping) {
// Your mapping overrides; e.g., mapping.Id(...);
3) Within YourProject.Data.NHibernateMaps.AutoPersistenceModelGenerator, append the following extension method to the mappings creation:
#) Update YourProject.Web/Scripts/jquery*.js with 1.3.2 versions available in Northwind sample project
#) Update YourProject.Web/Views/web.config to reflect the respective content from the Northwind sample project
#) Within YourProject.Web/Global.asax.cs, change the following line:
#) Within YourProject.Web/Global.asax.cs, modify the Init() to reflect the locking mechanism shown within
#) Within YourProject.Tests/App.config, update the nunit assembly redirect to go to version
#) Change calls to EntityIdSetter<>.SetIdOf() to EntityIdSetter.SetIdOf<>()
#) Update your Site.master to provide an overwritable title and to account for a known bug in MVC RC 1, described at
#) Either replace your CrudScaffolding project with a duplicate of the one from the Northwind project or use the guidance discussed in the below change log for modifications
#) (Optional) Add the following line to Global.asax.cs to Application_Start if you're client side code looks for dot-notation in generated input names:
HtmlHelper.IdAttributeDotReplacement = ".";
#) (Optional) Add Northwind.Web/Scripts/jquery-1.2.6.min-vsdoc.js and jquery-1.2.6-vsdoc.js to your project to enable jQuery IntelliSense
#) (Optional) Get rid of the code behind pages in favor of ViewMasterPage, ViewPage<Whatever>, ViewUserControl<Whatever> inheritance in the view's Master/Page/Control declaration. E.g.: Inherits="System.Web.Mvc.ViewPage<Employee>". Be sure to include System.Web.Mvc before ViewPage and either move your domain imports ABOVE the page declaration or fully qualify the namespaces of your model object.
#) (Optional) Add MvcBuildViews to YourProject.Web.csproj and alter the Target/AfterBuild, following the details in the ASP.NET MVC RC release notes
Changes to /src:
Solution Wide:
* BREAKING CHANGE ~ Changed Entity.ID to Entity.Id for compliance with naming conventions (When you upgrade, don't do a simple find and replace as you'll change IDictionary, GUID and other such items; also pay attention when updating your IAutoPersistenceModelGenerator)
VS Project Template:
* A CommonAssemblyInfo.cs is now included and added to all projects
* A YourProject.ApplicationServices class libraries now comes automatically with VS generated projects
CrudScaffolding Generator:
* Commented out "generator.Run()" by default to avoid inadvertent code generation
* Added reference to SharpArch.Core to have design by contract capablities
* Added reference to Inflector.Net.Inflector for pluralizing words
* Added assembly inclusion at the top of /Templates/ and
* Replaced all references to "Pluralizer.ToPlural" with "Inflector.Net.Inflector.Pluralize"
* Modified /Templates/Web/Views/*.tt page/control declarations, and added imports where necessary, to support removal of code-behind pages
* Deleted in favor of using Inflector.Net
* Deleted /Templates/Data/NHibernateMaps/ due to VS project template and Northwind now using Fluent NHibernate auto persistence model
* Deleted /Templates/Web/Views/ and because they're no longer necessary (nor recommended)
* Deleted / as the enum has been moved to the newly added /; had to also drop the include of this file from /Templates/
* Within /Templates/
- Dropped import of, and
- Dropped move of code behind and designer pages from MoveViewFilesTo()
- Dropped GenerateGeneralCodeBehindAndDesignerForViewPage() and all calls to it
- Dropped all calls to GeneralCodeBehindTemplate and GeneralDesignerTemplate
* Added / to have a more expressive and complete means of generating entities
* Replaced all use of namespaceHierarchy, domainObjectName, properties, and artifactsToGenerate with instance of entityScaffoldingDetails; e.g.,
- Replaced parameter set "domainObjectName, properties, namespaceHierarchy" with "entityScaffoldingDetails"
- Replaced "domainObjectName" with "entityScaffoldingDetails.EntityName"
- Replaced "namespaceHierarchy" with "entityScaffoldingDetails.NamespaceHierarchy"
- Replaced "artifactsToGenerate" with "entityScaffoldingDetails.ArtifactsToGenerate"
- Replaced "DomainObjectNamePlural" with "entityScaffoldingDetails.EntityNamePlural"
* Moved plural and camel case helper methods from /Templates/ to
* Added BaseTemplate.EntityBaseUrl to be able to retrieve the base URL of the entity being generated
* In each template, changed each constructor to accept EntityScaffoldingDetails and pass it to the constructor of
* Changed constructor of to accept EntityScaffoldingDetails and share it as a protected value to subclass templates
* Changed templates as follows (in this order):
- Replaced "DomainObjectNamePluralCamelCase" with "EntityScaffoldingDetails.EntityNamePluralCamelCase"
- Replaced "DomainObjectNamePlural" with "EntityScaffoldingDetails.EntityNamePlural"
- Replaced "DomainObjectNameCamelCase" with "EntityScaffoldingDetails.EntityNameCamelCase"
- Replaced "DomainObjectName" with "EntityScaffoldingDetails.EntityName"
- Carefully replaced "NamespaceHierarchy" with "EntityScaffoldingDetails.NamespaceHierarchy"
- Replaced "foreach (string propertyName in Properties.AllKey)" with "foreach (EntityProperty property in EntityScaffoldingDetails.EntityProperties)" and adjusted loop accordingly
* Within /Templates/Tests/Core/Web/Controllers/, deleted CanEnsureEntityCreationIsValid() method; it's doesn't prove anything with the new use of ModelState.IsValid on form submissions
* /DomainModel/BaseObject.cs: Modified Equals() to account for the fact that an object may be proxied by NHibernate when compared.
* /DomainModel/Entity.cs: Id is now excluded for XML serialization; see documentation FAQ for work around for Id serialization.
* /DomainModel/ValueObject.cs: == and != operator overloads have been added.
* /DomainModel/ValidatableObject.cs: This new class extracts the concrete validation that was being performed in Entity into a reusable superclass. (Entity now inherits from it.)
* BREAKING CHANGE ~ /PersistenceSupport/IRepository.cs: Changed GetAll and FindAll to return an IList rather than a List to be more loosely coupled.
* BREAKING CHANGE ~ /PersistenceSupport/NHibernate/INHibernateRepository.cs: Changed FindAll to return an IList rather than a List to be more loosely coupled.
* Between RC 1 and 2, added and then removed /NHibernate/FluentNHibernate/IAutoPeristenceModelConventionOverride.cs: In the RC 1 compatible code, I added this interface to serve as a base class for any Fluent NHibernate override classes; this was introduced because it's no longer allowed to inherit from AutoMap<> for overriding conventions. For RC 2, James Gregory, developer of Fluent NHibernate, was kind enough to port these capabilities into Fluent NHibernate itself; so this interface has been dropped in RC 2.
* Between RC 1 and 2, added and then removed /NHibernate/FluentNHibernate/AutoPersistenceModelExtensions.cs: In the RC 1 compatible code, I added this extension to AutoPersistenceModel to automatically apply any override classes from a specific assembly. With James Gregory's port of this functionality to Fluent NHibernate, this class has been dropped in the RC 2 compatible code.
* /NHibernate/Repository.cs: Changed GetAll and FindAll to return an IList rather than a List to be more loosely coupled.
* /NHibernate/NHibernateRepository.cs: Changed FindAll to return an IList rather than a List to be more loosely coupled.
* BREAKING CHANGE ~ /EntityIdSetter.cs: Changed use of EntityIdSetter from EntityIdSetter<>.SetIdOf() to EntityIdSetter.SetIdOf<>()
* /Areas/AreaViewEngine.cs: Added a needed "useCache" variable to FindPartialView() and FindView() for RC compatibility
* /CommonValidator/ValidatableModelBinder.cs: This new class inherits DefaultModelBinder to introduce domain driven validation to the binding process. (This is in contrast to the MVC IDataErrorInfo which uses exceptions for raising validation issues. See the class comments for more information.)
* WindsorExtensions.cs: Dropped RegisterController() and RegisterControllersByArea() extension methods; MvCContrib has this fixed now - so need need for the extensions anymore.
Northwind - All Projects
* Added CommonAssemblyInfo.cs to all projects and removed duplicate assembly info attributes.
* New class library to hold application services (see Evans' Domain Driven Design for more info about application services)
* Within Northwind.Web.csproj (and VS project template), added post compiler step as outlined in* Renamed Hibernate.cfg.xml to NHibernate.config so that you can't browse to it on the web server
* Global.asax.cs:
- Passed location of NHibernate.config to NHibernateSession.Init()
- For RC 1, I had within Application_Start, I added "ModelBinders.Binders.DefaultBinder = new ValidatableModelBinder();" to replace the default binder with one that seamlessly integrates CommonValidator capabilities; for RC 2 (the current release), I've removed this again to have more consistent post behavior between Create and Edit
* /Scripts/jquery*.js: Updated to 1.3.2
* /Views/Organization/Employees/Index.aspx: Changed the delete link to an input button within a form which includes an anti-forgery token; deletes should only happen via POST requests for better security
* /Organization/EmployeesController.cs:
- Replaced validation mechanism with ModelState.IsValid which now leverages ValidatableModelBinder
- Moved transfer of form properties to persistent object to within ModelState.IsValid path
- Dropped RollbackTransaction since it's no longer necessary
- Dropped use of MvcValidationAdapter.TransferValidationMessagesTo since it's done via ValidatableModelBinder
- Added ValidateAntiForgeryToken to the post actions
* /Northwind.Data/NHibernateMaps/MappingIntegrationTests.cs: Renamed "Hibernate.cfg.xml" parameter to "NHibernate.config" (discussed under Northwind.Web changes)
1.0 Beta (rev 337) - S#arp Architecture for ASP.NET MVC Beta with NHibernate 2.0.1
New and exciting in this release:
* CRUD Scaffolding generation is now available
* Added CommonServiceLocator to provide IoC agnosticism to the non-web layers
* You no longer need to register custom repositories to Castle's now done with voodoo magic (thanks Kyle Baley for the voodoo magic!)
* Added formal solution structure to help organize applications
* View "areas" are seamlessly supported as subfolders under the Views folder
* You no longer need to install ASP.NET MVC to create and edit S#arp Architecture projects
* NHibernate auto mapping is now available (thanks Jay Oliver!)
* Validation is now abstracted, similarly to CommonServiceLocator...use NHibernate Validator out of the box or supply your own! (thanks Luis Abreu for being a pain in the arse until this change was made! ;)
Assembly Dependencies:
* Castle 1.0 RC3
* Fluent NHibernate 0.1 (rev 207)
* Json.NET 3.5 Beta 2
* Microsoft.Practices.ServiceLocation 1.0 (CommonServiceLocator)
* NHibernate 2.0.1
* NHibernate.Validator 1.0
* MvcContrib Beta (rev 697)
* Rhino.Mocks
* System.Data.SQLite.DLL
Changes to /src:
SharpArch Solution
* All projects are now strongly signed with exception of SharpArch.Web.Castle (The MvcContrib dependency isn't signed; there's only one class in this SharpArch library, so you can move it to your project to sign everything.)
* Added support for Fluent NHibernate automapping (see for patch details which have been applied)
* BaseObject.cs ~ Introduced this base class to consolidate object comparison functionality used by both DomainObject and ValueObject
* BREAKING CHANGE ~ EnumDescription.cs: This class has been dropped from the library; it doesn't have anything to do with S#arp Architecture; if you miss it dearly, you can find it described at
* BREAKING CHANGE ~ Renamed IDomainObject.cs to IValidatable.cs to reflect what it's really doing; also simplified IValidatable to contain simply IsValid()
* BREAKING CHANGE ~ Dropped DomainObject.cs and PersistentObject.cs and replaced them with Entity.cs which now exists in /DomainModel namespace. Here are steps to take to accommodate:
1) Do a solution wide find and replace of "PersistentObject" with "Entity"
2) Change every call to ".ValidationMessages" to ".ValidationResults()"
3) Manually add "using SharpArch.Core.DomainModel;" onto every page having an Entity
* ValueObject.cs: Added this value-object base class to support this missing base class for DDD
* See for a more thorough summary of the changes to SharpArch.Core and the validation infrastructure
* BREAKING CHANGE ~ Renamed Repository.GetByProperties(), Repository.GetUniqueByProperties(), Repository.GetByExample(), Repository.GetUniqueByExample() to FindAll(properties/example) and FindOne(properties/example)
* BREAKING CHANGE ~ Repository.cs: This now implements the simpler IRepository<> instead of INHibernateRepository<>; Moved the NHibernate specific methods Get(id, lockMode), Load(id), Load(id, lockMode), FindAll(exampleInstance), FindOne(exampleInstance), Save(entity), Update(entity), Evict(entity) to NHibernateRepository<>; If you write a custom repository which needs to implement methods from INHibernateRepository<>, you'll want to inherit from this new NHibernateRepository<> class
* /NHibernate/NHibernateSession.cs: Added RegisterInterceptor(IInterceptor) to be optionally invoked after you've initialized NHibernate configuration
* /Areas/AreaRouteHelper.cs: New class for supporting controller/view "areas"
* /Areas/AreaViewEngine.cs: New class for replacing the default view engine for supporting use of areas
* /JsonNet/JsonNetResult.cs: New ActionResult for returning Json.NET result
* BREAKING CHANGE ~ /CommonValidator/MvcValidationAdapter.cs: Moved from /NHibernate/Validator/MvcValidationAdapter.cs
* Added this library to house extension methods for Castle related to registering controllers and custom repositories
Northwind Solution
* Modified solution structure to reflect the following
/MyProject - Contains MyProject.sln
/app - Contains the core project layers.
/lib - Contains the solution items for the deployable application.
/db - Contains database schema information; e.g., the result of scaffolding and/or NHibernate's schema export.
/docs - Project documents.
/logs - Output location for log files.
/build - Empty folder for housing build related stuff.
/lib - Contains the solution items for the tests project and all other non-deployable assemblies.
/CrudScaffolding - Customizable CRUD, scaffolding generation code.
* Modified solution to accommodate controller/view "areas"; the change were numerous and should be reviewed within the patch associated with
* Moved all employee related artifacts (controller, domain, views, etc.) under a namespace of "Organization" to show how areas are used
Northwind.Web.Controllers (formerly Northwind.Controllers)
* Added a reference to Microsoft.Practices.ServiceLocation.dll
* RouteRegistrar.cs: Registered map for "Root"; added ignore for favicon.ico
* Renamed this project from Northwind.Controllers to Northwind.Web.Controllers. To migrate this change to your own project:
In your project:
0) Before starting this, clear out all your compiled bin directories to avoid NHibernate getting confused with obsolete DLLs lying around
1) Renamed YourProject.Controllers to YourProject.Web.Controllers
2) In YourProject.Web.Controllers' project properties, renamed Assembly name and Default namespace of "YourProject.Controllers" with "YourProject.Web.Controllers"
3) Did a solution wide find and replace of "YourProject.Controllers" to "YourProject.Web.Controllers"
4) Via VS, added the folder "YourProject.Web/Controllers" under YourProject.Tests and moved the contents of YourProject.Tests to this new folder; finally deleted the YourProject.Controllers folder from the YourProject.Tests project
5) Successfully compiled all changes and closed VS
6) Renamed the YourProject.Controllers folder to YourProject.Web.Controllers
7) Reopened the SLN and replaced the missing project with the one from the renamed folder and then added a reference to YourProject.Tests and YourProject.Web
In CrudScaffolding:
1) Moved Templates/Controllers to Templates/Web/Controllers
2) Moved Templates/Tests/Controllers to Templates/Tests/Web/Controllers
3) Modified paths within Templates/ to account for the moved files
4) Did a *project* wide find and replace of ".Controllers" to ".Web.Controllers"
5) Within, modified the third line under the GenerateControllerAndTests() method to be the following:
string targetPathRoot = testsRootFolder + solutionName + ".Tests\\" + solutionName + ".Web\\Controllers\\";
6) Within, modified the third line under the AddFileToProject() method to be the following:
if (pathOfProjectFileToAddTo.IndexOf(project.Name + ".csproj") > -1) {
* Added a reference to Microsoft.Practices.ServiceLocation.dll
* Added a reference to Microsoft.Practices.ServiceLocation.dll
* Moved project to /NorthwindSample/tests/Northwind.Tests
* Added a reference to Microsoft.Practices.ServiceLocation.dll, Castle.Core.dll, Castle.MicroKernel.dll, Castle.Windsor.dll to support configuring IoC from the tests layer
* /Northwind.Controllers/RouteRegistrarTests.cs: Added call to "Clear()" the RouteTable during SetUp()
* /Northwind.Data/NHibernateMaps/MappingIntegrationTests.cs: Changed relative path to account for new solution structure; e.g., "../../../../app/Northwind.Web/Hibernate.cfg.xml"
* Added a reference to Microsoft.Practices.ServiceLocation.dll
* Default.aspx.cs: Modified RewritePath to pass in false for the rebasePath parameter
* Global.asax.cs: Added CommonServiceLocator support and removed implementation of IContainerAccessor (use CSL instead)
* Northwind.Web.csproj: Removed "{603c0e0b-db56-11dc-
be95-000d561079b0};" from top to remove dependency on ASP.NET MVC being installed
* web.config: Changed relative path to log4net output file to reflect new solution structure; e.g., <file value="../../logs/Northwind.Web.log"/>
* /CastleWindsor/CastleExtensions.cs: Added extension to find interfaces for custom repositories
* /CastleWindsor/ComponentRegistrar.cs: Replaced manual custom repository registrations with auto-registration of custom repositories; Added registration of IRepositoryWithTypedId and INHibernateRepositoryWithTypedId; Modified auto-bindings to account for the new NHibernateRepository<> and NHibernateRepositoryWithTypedId<,> classes
Northwind Solution Items
* Added NorthwindSample/Solution Items/CommonServiceLocator.WindsorAdapter.dll
* Added NorthwindSample/Solution Items/Microsoft.Practices.ServiceLocation.dll
0.9.114 - ASP.NET MVC Beta, NH 2.0.1, NHibernate.Validator, Fluent NHibernate, Castle Windsor
New and exciting:
* A Visual Studio 2008 template project has been added under /TemplatesAndCodeGen to get your own S#arp Architecture project up and running quickly
* Replaced Ninject with Castle Windsor
* Added support for behavior driven unit testing
* Unit tests now use an in-memory SQLite database for testing data access methods along with providing an integration verification mechanism to check mappings against a live database
Assembly Dependencies:
* Castle 1.0 RC3
* Fluent NHibernate 0.1
* NHibernate 2.0.1
* NHibernate.Validator 1.0
* MvcContrib Revision 635 (later than release from CodePlex)
* Rhino.Mocks
* System.Data.SQLite.DLL
Changes to /src:
** Search for "BREAKING CHANGE" below to find each of the breaking changes **
* BREAKING CHANGE ~ Moved NHibernate/RepositoryUnitTestsBase.cs to SharpArch.Testing.NUnit/NHibernate and renamed it to be DatabaseRepositoryTestsBase. To fix, simply add a "using SharpArch.Testing.NUnit.NHibernate;" to any test fixture class which inherits from RepositoryUnitTestsBase and rename the parent to DatabaseRepositoryTestsBase
* Added this new, stand-alone library to consolidate general, unit testing utilities
* PersistentObjectIdSetter.cs: Used to set the ID of a persistent object for unit testing purposes; this class was originally in Northwind.Tests
* Added this new, stand-alone library to support NUnit
* BehaviorSpecificiationTestsBase.cs: This optional text fixture base class provides a base class for BDD unit tests, as described at
* SyntaxHelpers.cs: This optional extensions class adds a number of fluent NUnit syntax capabilities. To use, simply add a reference to SharpArch.Testing.NUnit to have them available from your unit tests.
* NHibernate/DatabaseRepositoryTestsBase.cs: This is the old SharpArch.Data/NHibernate/RepositoryUnitTestsBase.cs class provided for backwards compatibility. The preferred mechanism for database unit testing is using an in-memory database, described next.
* NHibernate/RepositoryBehaviorSpecificationTestsBase.cs: Provides an optional base class for developing behavior driven unit tests against an auto-generated database, suggested to be in-memory, SqlLite database. (See Northwind.Tests for an example.)
* NHibernate/RepositoryTestsBase.cs: Behaves similarly to the old SharpArch.Data/NHibernate/RepositoryUnitTestsBase.cs but auto-generates the database, suggested to be in-memory, SqlLite database. (See Northwind.Tests for an example.)
* BREAKING CHANGE ~ Ninject/ControllersAutoBindModule.cs: This class has been deleted. If you need it for backwards compatibility, you can get the code for this class from version 0.9.72 and put it into your application.
SharpArch Solution Items
* BREAKING CHANGE ~ Deleted Ninject.Conditions.dll and Ninject.Core.dll. If you need them for backwards compatibility, you can get them from version 0.9.72 and add them to your application.
* Updated MvcContrib*.dll dependencies
* RouteRegistrar.cs: Added this class to pull route registration into the controllers layer.
* /CastleWindsor/: Added support for Castle Windsor configuration within the class ComponentRegistrar.cs
* /NinjectModuldes/: Deleted this folder and replaced it with /CastleWindsor/
* Hibernate.cfg.xml: Extracted NHibernate settings to this file and set the "Copy to Output Directory" to "Copy always"
* Global.asax.cs: Modified Global.asax.cs to pass in path to the HBM dll using "~" for the relative path; dropped the optional path to the Hibernate.cfg.xml now that it's being copied to the output directory (i.e., to the /bin directory); moved route registration to /Northwind.Controllers/RouteRegistrar.cs; added Castle Windsor configuration.
* web.config: Dropped assembly redirect for Ninject and added log4net configuration
* App.config: Removed "nhibernate.config.path" from appSettings; it now uses Hibernate.cfg.xml, discussed next
* Hibernate.cfg.xml: Added this file and set its "Copy to Output Directory" to "Copy always"; this now uses an in-memory SqlLite database for DB tests
* All DB test fixtures now inherit from either RepositoryTestsBase or RepositoryBehaviorSpecificationTestsBase using the in-memory database
* Northwind.Data/NHibernateMaps/MappingIntegrationTests.cs: Test fixture which tests every mapping file against the database sepcified in the application's "live" database NHibernate configuration file (e.g., the one found within the Northwind.Web project); this ensures that the "live" database is compliant with the mapping files since the unit tests are now using an in-memory database.
* Added this new, stand-alone library to demonstrate unit testing against a "live" development database. The preferred mechanism is to use an in-memory database, as demonstrated within Northwind.Tests, but this is here to show backward compatibility for the previous approach.
Northwind Solution Items
* Deleted Ninject.Conditions.dll, Ninject.Core.dll and MvcContrib.Ninject.dll
* Added Castle.MicroKernel.dll, Castle.Windsor.dll and MvcContrib.Castle.dll
** Version Acknowledgements **
* A big thanks goes out to Lee Carter for providing code for running DB unit tests within an in-memory SQLLite database.
0.9.72 - ASP.NET MVC Beta, NH 2.0.1, Ninject 1.0, NHibernate.Validator 1.0, Fluent NHibernate 0.1
Migrating from 0.8.1 to 0.9.0 (see the Northwind sample code for implementation examples):
* Follow instructions for upgrading to ASP.NET MVC Beta. There were respective modifications made to web.config and assembly dependencies. Also included changes to Global.asax.cs and the inclusion of Default.aspx.cs
* Change the name of the "web.config" AppSetting within Northwind.Tests/App.config to "nhibernate.config.path"
* Add a new AppSetting within Northwind.Tests/App.config called "nhibernate.mapping.assembly" which contains the name of the assembly which holds the mapping artifacts
* Add an assembly redirect for NHibernate to app.config and web.config; Fluent NHibernate is a little behind
* Change any calls to myDao.CommitChanges() to myDao.DbContext.CommitChanges()
* Change any references to DomainSignatureComparable to DomainObject
* If you've overridden HasSameDomainObjectSignatureAs, changes the parameter type to IDomainObject (instead of DomainSignatureComparable)
* Rename references to SharpArch.Core.PersistenceSupport.IDao/IDaoWithTypedId to IRepository/IRepositoryWithTypedId (as a number of developers have rightly indicated is more inline with DDD)
* Rename references to SharpArch.Data.NHibernate.GenericDao/GenericDaoWithTypedId to Repository/RepositoryWithTypedId
* Rename references to SharpArch.Data/NHibernate/DaoTests.cs to RepositoryUnitTestsBase.cs
* Greatly simplified IRepository and moved NHibernate specific methods to SharpArch.Core/PersistenceSupport/NHibernate/INHibernateRepository.cs; consequently, SharpArch.Core/PersistenceSupport/IRepository.cs, which was IDao.cs, now contains the following breaking changes:
- LoadAll was changed to GetAll (changed to standardize "Get" as the retrieval keyword);
- Get(id, lockMode), GetByExample, GetUniqueByExample, Load(id), Load(id, lockMode), Save, Update and Evict were all moved to SharpArch.Core.PersistenceSupport.NHibernate.INHibernateRepository.
IRepository was simplified to provide a simpler mechanism that is more NHibernate agnostic and is simpler to understand and use. You may still wish to use the NHibernate-specific one. Consequently, decide if you'd like to use SharpArch.Core.PersistenceSupport.IRepository/IRepositoryWithTypedId or SharpArch.Core.PersistenceSupport.NHibernate.INHibernateRepository/INHibernateRepositoryWithTypedId and adjust your code, accordingly. There's nothing to stop you from using IRepository most of the time and INHibernateRepository on occassion...but I'd only recommend using it when absolutely necessary. For example, the only time the Northwind sample uses it is to support Save vs. Update for objects with assigned IDs (which are a bad practice to use anyway).
* Optionally rename your *Dao.cs classes to *Repository.cs to be consistent with the IRepository base interface.
* Optionally move NHibernate settings out of web.config into Hibernate.cfg.xml (the Northwind contains an example); if you do so, be sure to change the path in MyProject.Tests/app.config to point to the externalized file
* Optionally migrate your HBM files to Fluent NHibernate class maps within MyProject.Data. If you do so, be sure to delete the HBMs (or simply set their compile behavior to "Content" rather than "Embedded Resource" during the migration. You'll then need to change the mapping assembly information for NHibernate. REGARDLESS, you'll need to remove the assembly mapping property from your NHibernate configuration settings and modify the NHibernate session initialization within Global.asax.cs; see Northwind.Web/Global.asax.cs for an example. Currently, you have to provide the full path to the requested resources; I'm looking to simplify this if possible.
*** Non Breaking Changes ***
The documentation within <root>/docs has been completely updated; I highly recommend you review it to see changes in action, particularly with respect to Fluent NHibernate.
Modifications to <root>/bin:
* All dependencies needed for your own project are now included in the bin folder
Modifications to SharpArch:
* SharpArch.Core/PersistenceSupport: Added IPersistentObject and IDomainSignatureComparable to provide your own implementation, if you feel so inclined
* SharpArch.Data/NHibernate/NHibernateSession.cs: Inclusion of NHibernate.Validator. Optional NHibernate.Validator config file may be passed to NHibernateSession.Init within Global.asax.cs
* SharpArch.Data/NHibernate/NHibernateSession.cs: Init has been overloaded to to accept ISessionStorage without config file info.
* Marked both DomainSignatureAttribute and DomainSignatureComparable as Serializable (thanks athmer!)
* The Equals/GetHashCode has been split; Equals no longer uses the result of GetHashCode for the basis of equality checking. The affected classes include SharpArch.Core/DomainSignatureComparable.cs and SharpArch.Core/PersistenceSupport/PersistentObject.cs. Although the underlying mechanism for these methods were altered, it should introduce no breaking changes.
* The methods GetByProperties(IDictionary<string, object>, propertyValuePairs) and GetUniqueByProperties have been added to IRepository and Repository. A unit test using this feature has been added to Northwind.Tests/Northwind.Data/CustomerDaoTests.cs
* IRepository now exposes IDbContext which provides capabilities such as CommitChanges, Begin/Commit/RollbackTransaction
* Added validation support methods to DomainObject
Modifications to Northwind sample:
* Added full CRUD with validation for employee objects
* Modified Northwind.Core/Order.cs to show an example of overriding HasSameDomainObjectSignatureAs()
* Updated dynamic links to use Html.ActionLink
* Added a many-to-many example; specifically:
- Northwind.Core
* Employee has a many-to-many relationship to Territory objects.
* Territory has a many-to-many relationship back to Employee objects. This is the inverse side of the relationship.
* Region has a one-to-many relationship to Territory; the relationship is defined in the Territory HBM.
- Northwind.Tests
* Northwind.Core/RegionTests.cs, TerritoryTests.cs, and EmployeeTests.cs test the domain model of the new classes.
* Northwind.Data/EmployeeDaoTests.cs and TerritoryDaoTests.cs test the many-to-many relationships in the database along with the many-to-one from Territory to Region.
* Made general clean ups to make the code simpler and with less typing (e.g., changed "<%= (ViewData.Model as Customer).CompanyName%>" to simply "<%= ViewData.Model.CompanyName%>")
0.8.1 - MVC Preview 5, NH 2.0.1 and Ninject 1.0
Baseline history record