Permalink
Browse files

Some fixes in UoW.

Sample application doing something useful already.
  • Loading branch information...
1 parent e25e2b0 commit c98c73eaa31f93bff93a36e8a50694b27c19bb06 @Kostassoid committed May 1, 2012
@@ -45,6 +45,7 @@
</Compile>
<Compile Include="ICommandResult.cs" />
<Compile Include="ICommand.cs" />
+ <Compile Include="IConsumerOf.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@@ -12,16 +12,10 @@
// specific language governing permissions and limitations under the License.
//
-namespace Kostassoid.BlogNote.Host.Service
+namespace Kostassoid.Anodyne.CommandBus
{
- using Anodyne.CommandBus;
- using Contracts;
-
- public class UserService : IUserService
+ public interface IConsumerOf<in TCommand> where TCommand : ICommand
{
- public ICommandResult Send(ICommand command)
- {
- return null;
- }
+ void Handle(TCommand command);
}
}
@@ -25,6 +25,9 @@ public static void UseMongoDataAccess(this IConfiguration configuration, string
cfg.Container.For<IDataSessionFactory>()
.Use(() => new MongoDataSessionFactory(NormalizeConnectionString(databaseServer), databaseName, new ContainerOperationResolver(cfg.Container)));
+
+ UnitOfWork.SetFactory(cfg.Container.Get<IDataSessionFactory>());
+
//cfg.Container.ForAll<IDataOperation>().Use<MongoDataSessionFactory>();
}
@@ -18,6 +18,7 @@ namespace Kostassoid.Anodyne.MongoDb
using MongoDB.Bson;
using MongoDB.Driver;
using DataAccess.Operations;
+ using MongoDB.Driver.Builders;
using global::System;
public class MongoDataSession : DataSession, IDataSessionEx
@@ -39,10 +40,21 @@ public override IRepository<TRoot> GetRepository<TRoot>()
return new MongoRepository<TRoot>(_nativeSession);
}
+ private BsonValue GetIdValue(object id)
+ {
+ if (id is Guid) return (Guid)id;
+ if (id is string) return (string)id;
+ if (id is int) return (int)id;
+ if (id is long) return (long)id;
+ if (id is ObjectId) return (ObjectId)id;
+
+ throw new InvalidOperationException(string.Format("Unsupported _id type : {0}", id.GetType().Name));
+ }
+
protected override IAggregateRoot FindOne(Type type, object id)
{
var collection = _nativeSession.GetCollection(type);
- return collection.FindOneByIdAs(type, id.ToBson()) as IAggregateRoot;
+ return collection.FindOneByIdAs(type, GetIdValue(id)) as IAggregateRoot;
}
protected override void SaveOne(Type type, IAggregateRoot root)
@@ -54,7 +66,7 @@ protected override void SaveOne(Type type, IAggregateRoot root)
protected override void RemoveOne(Type type, object id)
{
var collection = _nativeSession.GetCollection(type);
- collection.Remove(MongoDB.Driver.Builders.Query.EQ("_id", id.ToBson()));
+ collection.Remove(Query.EQ("_id", GetIdValue(id)));
}
}
@@ -16,6 +16,7 @@ namespace Kostassoid.Anodyne.System.Wcf
{
public interface IWcfServiceProvider
{
+
}
}
@@ -14,6 +14,7 @@
namespace Kostassoid.BlogNote.Contracts
{
+ using System;
using System.ServiceModel;
using Anodyne.CommandBus;
@@ -22,5 +23,8 @@ public interface IUserService
{
[OperationContract]
ICommandResult Send(ICommand command);
+
+ [OperationContract]
+ Guid EnsureUserExists(string name, string email);
}
}
@@ -77,7 +77,8 @@
<Compile Include="Domain\UserCreated.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Service\IUserService.cs" />
+ <Compile Include="Service\UserService.cs" />
+ <Compile Include="Startup\CommandConsumersRegistration.cs" />
<Compile Include="Startup\DataAccessConfiguration.cs" />
<Compile Include="Startup\WcfServicesRegistration.cs" />
<Compile Include="BlogNoteSystem.cs" />
@@ -31,6 +31,7 @@ public override void OnConfigure(IConfiguration c)
c.OnStartupPerform<DataAccessConfiguration>();
c.OnStartupPerform<WcfServicesRegistration>();
+ c.OnStartupPerform<CommandConsumersRegistration>();
c.OnShutdownPerform<WcfServicesRegistration>();
}
@@ -17,7 +17,7 @@ namespace Kostassoid.BlogNote.Host.Domain
using Anodyne.Common.CodeContracts;
using Anodyne.Common.Tools;
using Anodyne.Domain.Base;
- using global::System;
+ using System;
public class User : AggregateRoot<Guid>
{
@@ -39,7 +39,6 @@ protected User()
public static User Create(string name, string email)
{
Requires.NotNullOrEmpty(name, "name");
- Requires.NotNullOrEmpty(email, "email");
var user = new User();
@@ -64,7 +63,7 @@ protected void OnCreated(UserCreated @event)
public void UpdatePosts(uint posts)
{
- Requires.True(posts >= Posts, "posts", "We can't actually decrease Posts, by design");
+ Requires.True(posts >= Posts, "posts", "We can't actually delete posts, by design");
Apply(new UserPostsUpdated(this, posts));
}
@@ -0,0 +1,42 @@
+// Copyright 2011-2012 Anodyne.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+// this file except in compliance with the License. You may obtain a copy of the
+// License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+
+namespace Kostassoid.BlogNote.Host.Service
+{
+ using System;
+ using System.Linq;
+ using Anodyne.CommandBus;
+ using Anodyne.DataAccess;
+ using Contracts;
+ using Domain;
+
+ public class UserService : IUserService
+ {
+ public ICommandResult Send(ICommand command)
+ {
+ return null;
+ }
+
+ public Guid EnsureUserExists(string name, string email)
+ {
+ using (var uow = new UnitOfWork())
+ {
+ var foundUser = uow.Query<User>().All().FirstOrDefault(u => u.Name == name);
+ if (foundUser != null) return foundUser.Id;
+
+ return User.Create(name, email).Id;
+ }
+ }
+ }
+}
@@ -0,0 +1,30 @@
+// Copyright 2011-2012 Anodyne.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+// this file except in compliance with the License. You may obtain a copy of the
+// License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+
+namespace Kostassoid.BlogNote.Host.Startup
+{
+ using Anodyne.CommandBus;
+ using Anodyne.Common.Reflection;
+ using Anodyne.System;
+ using Anodyne.System.Configuration;
+
+ public class CommandConsumersRegistration : IStartupAction
+ {
+ public void OnStartup(IConfigurationSettings configuration)
+ {
+ //configuration.Container.For(typeof(IConsumerOf<>)).UseAll(From.Assemblies(a => a.FullName.Contains(Const.ProjectName)));
+ }
+
+ }
+}
@@ -30,11 +30,13 @@ public void OnStartup(IConfigurationSettings configuration)
var windsorContainer = (configuration.Container as WindsorContainerAdapter).NativeContainer;
var userServiceModel = new DefaultServiceModel()
- .AddBaseAddresses("http://localhost:1000/")
- .AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding()).At("UserService"))
+ .AddBaseAddresses(Configured.From.AppSettings("UserServiceUrl"))
+ .AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding()))
.PublishMetadata(o => o.EnableHttpGet());
windsorContainer.Register(Component.For<IUserService>().ImplementedBy<UserService>().AsWcfService(userServiceModel));
+
+ //Publish<TService>().ImplementedBy<TImpl>().At(Endpoint.)
}
public void OnShutdown(IConfigurationSettings configuration)
@@ -3,5 +3,6 @@
<appSettings>
<add key="DatabaseServer" value="mongodb://localhost:27001"/>
<add key="DatabaseName" value="BlogNote"/>
+ <add key="UserServiceUrl" value="http://localhost:10000/UserService"/>
</appSettings>
</configuration>
@@ -36,10 +36,20 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Castle.Core">
+ <HintPath>..\..\packages\Castle.Core.3.0.0.4001\lib\net40-client\Castle.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Castle.Facilities.WcfIntegration">
+ <HintPath>..\..\Libs\Castle\Castle.Facilities.WcfIntegration.dll</HintPath>
+ </Reference>
+ <Reference Include="Castle.Windsor">
+ <HintPath>..\..\packages\Castle.Windsor.3.0.0.4001\lib\net40\Castle.Windsor.dll</HintPath>
+ </Reference>
<Reference Include="EntityFramework">
<HintPath>..\..\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="System.Data.Entity" />
+ <Reference Include="System.ServiceModel" />
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
@@ -64,9 +74,13 @@
<Reference Include="System.EnterpriseServices" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Common\ControllersInstaller.cs" />
+ <Compile Include="Common\WindsorControllerFactory.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
+ <Compile Include="Models\UserModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -132,12 +146,27 @@
<Content Include="Views\Shared\_Layout.cshtml" />
</ItemGroup>
<ItemGroup>
- <Folder Include="Controllers\" />
- <Folder Include="Models\" />
+ <Content Include="Views\Home\Blog.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Main\Anodyne-Common\Anodyne-Common.csproj">
+ <Project>{2D6AC91A-29E5-4700-8E16-58D87AB98563}</Project>
+ <Name>Anodyne-Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\BlogNote-Contracts\BlogNote-Contracts.csproj">
+ <Project>{20B9EE59-59E5-4577-A937-61371685DA3E}</Project>
+ <Name>BlogNote-Contracts</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Views\Home\Index.cshtml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Query\Model\" />
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -153,12 +182,11 @@
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
- <UseIIS>False</UseIIS>
+ <UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>18741</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
- <IISUrl>
- </IISUrl>
+ <IISUrl>http://localhost/BlogNote-Web</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -0,0 +1,18 @@
+namespace Kostassoid.BlogNote.Web.Common
+{
+ using System.Web.Mvc;
+ using Castle.MicroKernel.Registration;
+ using Castle.MicroKernel.SubSystems.Configuration;
+ using Castle.Windsor;
+
+ public class ControllersInstaller : IWindsorInstaller
+ {
+ public void Install(IWindsorContainer container, IConfigurationStore store)
+ {
+ container.Register(
+ AllTypes.FromThisAssembly().BasedOn<IController>()
+ //.If(Component.IsInSameNamespaceAs<HomeController>())
+ .If(t => t.Name.EndsWith("Controller")).LifestyleTransient());
+ }
+ }
+}
@@ -0,0 +1,34 @@
+namespace Kostassoid.BlogNote.Web.Common
+{
+ using System;
+ using System.Web;
+ using System.Web.Mvc;
+ using System.Web.Routing;
+ using Castle.MicroKernel;
+
+ public class WindsorControllerFactory : DefaultControllerFactory
+ {
+ private readonly IKernel _kernel;
+
+ public WindsorControllerFactory(IKernel kernel)
+ {
+ _kernel = kernel;
+ }
+
+ public override void ReleaseController(IController controller)
+ {
+ _kernel.ReleaseComponent(controller);
+ }
+
+ protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
+ {
+ if (controllerType == null)
+ {
+ throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
+ }
+
+ var controller= (Controller)_kernel.Resolve(controllerType);
+ return controller;
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit c98c73e

Please sign in to comment.