EditIdentifiable Services
EditAlready available services
Currently, the CoreRepository contains at least four service components:
- Session management
- Generic object manipulation (CRUD)
- Site specific services
- User specific services
Besides that other Cuyahoga.Core.* namespaces may contain classes that could be converted to service components as well, for example Cuyahoga.Core.Util.Encryption could be a candidate.
EditFuture services
To minimize repetitive code on modules, additional services can be introduced:
- FileService for managing a centralized file repository
- WorkflowService for creating simple processes (e.g. content approval)
- VersioningService for saving and retrieving different versions of content
- ExportService, generic (xml, csv?) export (by category, content-type, node etc.)
EditNeeded changes for Windsor integration
EditCuyahoga.Core (CoreRepository)
By integrating WindsorContainer changes would involve:
- Defining contracts (interface definitions) for the different services contained in CoreRepository
- Creating concrete implementations (using the available) for these contracts
- Creating a CuyahogaContainer (subclass WindsorContainer to ease the initializations/configuration)
- Configuring Container to register available service components and facilities
EditCuyahoga.Web
- Add neccessary entries to web.config.
- Make the container available through the HttpApplication.
EditAdditionally usable components with Windsor
EditNHiberate facility
This facility provides extended services for NHibernate with WindsorContainer:
- Session management
- Transaction management
- Flexible configuration (e.g. testing/ debug environment)
For detailed information see:
http://www.castleproject.org/index.php/Facility:NHibernate CastleProject: NHibernate FacilityEditEvent Wiring facility
Implements the Publisher/Subscriber pattern
EditLogging facility
Decouple logging from log4net by using a common interface
More detail see:
http://www.castleproject.org/index.php/Facility:Logging CastleProject: Logging
EditConclusion and estimated impact on existing code
Integration of WindsorContainer could be hidden from other components by converting the CoreRepository to a facade through which the new services can be accessed in the same way as is.
Introducing the NHibernate facility will affect all areas where the currently implemented SessionFactory is being used.
After reading through the NHibernate facility code, I get the strong feeling that there is not much it could do better than Cuyahoga's existing NHibernate helpers (Session, Generic CRUD etc.).
So at the moment, if we only wanted IoC, we could just use the container (Windsor, or even the "plain" Microkernel would do the job) and focus on "componentizing" the existing code.
EditCode samples
EditIUserService
Following code shows, how the contract for the newly created UserService could look like.
using System;
using System.Collections;
using Cuyahoga.Core.Domain;
namespace Cuyahoga.Core.Service
{
public interface IUserService
{
User GetUserByUsernameAndPassword(string username, string password);
User GetUserByUsernameAndEmail(string username, string email);
IList FindUsersByUsername(string searchString);
}
}
EditISiteService
using System;
using System.Collections;
using Cuyahoga.Core.Domain;
namespace Cuyahoga.Core.Service
{
public interface ISiteService
{
//site
Site GetSiteBySiteUrl(string siteUrl);
SiteAlias GetSiteAliasByUrl(string url);
IList GetSiteAliasesBySite(Site site);
//node
IList GetRootNodes(Site site);
Node GetRootNodeByCultureAndSite(string culture, Site site);
Node GetNodeByShortDescriptionAndSite(string shortDescription, Site site);
IList GetNodesByTemplate(Template template);
void UpdateNode(Node node, bool propagatePermissionsToChildNodes, bool propagatePermissionsToSections);
void DeleteNode(Node node);
void PropagatePermissionsToChildNodes(Node parentNode, bool propagateToSections);
void PropagatePermissionsToSections(Node node);
//menu
IList GetMenusByRootNode(Node rootNode);
//section
IList GetSortedSectionsByNode(Node node);
IList GetUnconnectedSections();
IList GetTemplatesBySection(Section section);
//moduletype
IList GetSectionsByModuleTypes(IList moduleTypes);
}
}
EditCuyahogaContainer
By subclassing WindsorContainer, all neccessary initilization can be included.
namespace Cuyahoga.Core
{
using System;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using Castle.MicroKernel;
//using Castle.Facilities.AutomaticTransactionManagement;
using Castle.Facilities.NHibernateIntegration;
public class CuyahogaContainer : WindsorContainer
{
public CuyahogaContainer() : this( new XmlInterpreter("../app_config.xml") )
{
}
public CuyahogaContainer(XmlInterpreter interpreter) : base(interpreter)
{
Init();
}
public void Init()
{
RegisterFacilities();
RegisterComponents();
//SubcribeForEvents();
}
private void RegisterFacilities()
{
AddFacility( "nhibernate", new NHibernateFacility() );
//AddFacility( "transaction", new TransactionFacility() );
}
protected void RegisterComponents()
{
AddComponent( "user.service", typeof(UserService) );
}
protected void SubcribeForEvents()
{
}
}
}
EditCuyahogaHttpApplication
public class CuyahogaHttpApplication : HttpApplication, IContainerAccessor
{
private static WindsorContainer container;
public void Application_OnStart()
{
container = new CuyahogaContainer();
}
public void Application_OnEnd()
{
container.Dispose();
}
public IWindsorContainer Container
{
get { return container; }
}
}