Permalink
Browse files

Replaced svc file with dynamic routing.

  • Loading branch information...
1 parent 9605c48 commit 34964159307381ef2af0388d4b3295c0de32989d @object committed Apr 5, 2012
View
@@ -4,7 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 11.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D0D2CB2F-C630-4ABF-A298-3744D1CC44E6}"
ProjectSection(SolutionItems) = preProject
CommonAssemblyInfo.cs = CommonAssemblyInfo.cs
- ConnectionStrings.config = ConnectionStrings.config
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataServiceProvider", "DataServiceProvider\DataServiceProvider.csproj", "{6B6D1F18-EABE-4219-B86A-D18FB61C9DE0}"
@@ -90,11 +90,10 @@
<Compile Include="TestService.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="..\ConnectionStrings.config">
- <Link>ConnectionStrings.config</Link>
+ <None Include="App.config" />
+ <None Include="ConnectionStrings.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
- <None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
@@ -31,7 +31,7 @@ private void PopulateData(DSPInMemoryContext dspContext, MongoContext mongoConte
var collection = mongoContext.Database.GetCollection(resourceSet.Name);
foreach (var document in collection.FindAll())
{
- var resource = MongoDSPConverter.CreateDSPResource(document, metadata, MongoMetadata.RootNamespace, resourceSet.Name);
+ var resource = MongoDSPConverter.CreateDSPResource(document, metadata, resourceSet.Name);
storage.Add(resource);
}
}
@@ -27,6 +27,11 @@ public MongoDatabase Database
get { return this.database; }
}
+ public static IEnumerable<string> GetDatabaseNames(string connectionString)
+ {
+ return MongoServer.Create(connectionString).GetDatabaseNames();
+ }
+
public void Dispose()
{
this.database.Server.Disconnect();
@@ -12,10 +12,11 @@ internal static class MongoDSPConverter
{
private static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- public static DSPResource CreateDSPResource(BsonDocument document, DSPMetadata metadata, string namespaceName, string collectionName)
+ public static DSPResource CreateDSPResource(BsonDocument document, DSPMetadata metadata, string resourceName, string ownerPrefix = null)
{
ResourceType resourceType;
- metadata.TryResolveResourceType(string.Format("{0}.{1}", namespaceName, collectionName), out resourceType);
+ string qualifiedResourceName = string.IsNullOrEmpty(ownerPrefix) ? resourceName : MongoMetadata.GetComplexTypeName(ownerPrefix, resourceName);
+ metadata.TryResolveResourceType(string.Join(".", MongoMetadata.RootNamespace, qualifiedResourceName), out resourceType);
var resource = new DSPResource(resourceType);
foreach (var element in document.Elements)
@@ -26,7 +27,7 @@ public static DSPResource CreateDSPResource(BsonDocument document, DSPMetadata m
}
else if (element.Value.GetType() == typeof(BsonDocument))
{
- resource.SetValue(element.Name, CreateDSPResource(element.Value.AsBsonDocument, metadata, string.Join(".", namespaceName, collectionName), element.Name));
+ resource.SetValue(element.Name, CreateDSPResource(element.Value.AsBsonDocument, metadata, element.Name, MongoMetadata.GetComplexTypePrefix(resourceName)));
}
else if (element.Value.GetType() == typeof(BsonArray))
{
@@ -15,6 +15,7 @@ public class MongoMetadata
public static readonly Type MappedObjectIdType = typeof(string);
public static readonly string ContainerName = "MongoContext";
public static readonly string RootNamespace = "Mongo";
+ public static readonly bool UseGlobalComplexTypeNames = true;
public DSPMetadata CreateMetadata(string connectionString)
{
@@ -80,7 +81,8 @@ protected void PopulateMetadata(DSPMetadata metadata, MongoContext context)
else
{
resourceType = RegisterResourceType(metadata, context,
- string.Join(".", collectionName, element.Name), element.Value.AsBsonDocument, ResourceTypeKind.ComplexType);
+ GetComplexTypeName(collectionName, element.Name),
+ element.Value.AsBsonDocument, ResourceTypeKind.ComplexType);
}
metadata.AddComplexProperty(collectionType, element.Name, resourceType);
}
@@ -151,5 +153,15 @@ private static Type GetElementType(BsonElement element)
}
}
}
+
+ internal static string GetComplexTypePrefix(string ownerName)
+ {
+ return UseGlobalComplexTypeNames ? string.Empty : ownerName;
+ }
+
+ internal static string GetComplexTypeName(string collectionName, string resourceName)
+ {
+ return UseGlobalComplexTypeNames ? resourceName : string.Join("__", collectionName, resourceName);
+ }
}
}
@@ -66,7 +66,7 @@ public IEnumerable<DSPResource> GetEnumerableCollection(IEnumerator<BsonDocument
{
while (enumerator.MoveNext())
{
- yield return MongoDSPConverter.CreateDSPResource(enumerator.Current, MongoQueryableDataService.Metadata, MongoMetadata.RootNamespace, this.collectionName);
+ yield return MongoDSPConverter.CreateDSPResource(enumerator.Current, MongoQueryableDataService.Metadata, this.collectionName);
}
yield break;
}
@@ -17,7 +17,7 @@
<xsl:template match="wix:Component[wix:File/@Source='$(var.Mongo.DataService.ProjectDir)\Web.Release.config']" >
<xsl:value-of select="parent" />
</xsl:template>
- <xsl:template match="wix:Component[wix:File/@Source='$(var.Mongo.DataService.ProjectDir)\..\ConnectionStrings.config']" >
+ <xsl:template match="wix:Component[wix:File/@Source='$(var.Mongo.DataService.ProjectDir)\ConnectionStrings.config']" >
<xsl:value-of select="parent" />
</xsl:template>
@@ -6,7 +6,7 @@
<ProductVersion>3.5</ProductVersion>
<ProjectGuid>{fd0bc7e5-01f3-4a89-9422-5bb2597272be}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
- <OutputName>Mongo.DataService.Setup</OutputName>
+ <OutputName>MongOData.Setup</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
@@ -81,18 +81,18 @@
<!-- Create App_Data. -->
<ComponentRef Id="WebSiteAppData" />
- <!-- Perform changes in the web.config file. -->
+ <!-- Perform changes in the ConnectionStrings.config file. -->
<ComponentRef Id="ConnectionStringsCmp" />
</Feature>
</Feature>
<DirectoryRef Id="WebSiteDirectory">
- <!-- Component handling the web.config -->
+ <!-- Component handling the ConnectionStrings.config -->
<Component Id="ConnectionStringsCmp" Guid="">
- <!-- Copy web.config to MYWEBWEBSITE folder. -->
+ <!-- Copy web.config to WebSiteDirectory folder. -->
<File Id="ConnectionStringsFile" KeyPath="yes"
- Source="$(var.Mongo.DataService.ProjectDir)\..\ConnectionStrings.config" Vital="yes" />
+ Source="$(var.Mongo.DataService.ProjectDir)\ConnectionStrings.config" Vital="yes" />
<util:XmlFile Id="ModifyConnectionString"
Action="setValue"
Permanent="yes"
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings>
- <add name="MongoDB" connectionString="mongodb://localhost/test?strict=true"/>
+ <add name="MongoDB" connectionString="mongodb://localhost/*?strict=true"/>
</connectionStrings>
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="Mongo.DataService.Global" Language="C#" %>
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data.Services;
+using System.Linq;
+using System.ServiceModel.Activation;
+using System.Web;
+using System.Web.Routing;
+using System.Web.Security;
+using System.Web.SessionState;
+using Mongo.Context;
+using Mongo.DataService;
+
+namespace Mongo.DataService
+{
+ public class Global : System.Web.HttpApplication
+ {
+
+ protected void Application_Start(object sender, EventArgs e)
+ {
+ RegisterRoutes();
+ }
+
+ protected void Session_Start(object sender, EventArgs e)
+ {
+
+ }
+
+ protected void Application_BeginRequest(object sender, EventArgs e)
+ {
+
+ }
+
+ protected void Application_AuthenticateRequest(object sender, EventArgs e)
+ {
+
+ }
+
+ protected void Application_Error(object sender, EventArgs e)
+ {
+
+ }
+
+ protected void Session_End(object sender, EventArgs e)
+ {
+
+ }
+
+ protected void Application_End(object sender, EventArgs e)
+ {
+
+ }
+
+ private void RegisterRoutes()
+ {
+ DataServiceHostFactory factory = new DataServiceHostFactory();
+ var databaseNames = MongoContext.GetDatabaseNames(ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);
+ foreach (var databaseName in databaseNames)
+ {
+ RouteTable.Routes.Add(new ServiceRoute(databaseName, factory, typeof(MongOData)));
+ }
+ }
+ }
+}
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data.Services;
+using System.Data.Services.Common;
+using System.Text.RegularExpressions;
+using System.Web;
+using Mongo.Context;
+using Mongo.Context.Queryable;
+
+namespace Mongo.DataService
+{
+ public class MongOData : MongoQueryableDataService
+ {
+ public MongOData()
+ : base(BuildConnectionString())
+ {
+ }
+
+ public static void InitializeService(DataServiceConfiguration config)
+ {
+ config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
+ config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
+ config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
+ config.DataServiceBehavior.AcceptCountRequests = true;
+ config.DataServiceBehavior.AcceptProjectionRequests = true;
+ config.UseVerboseErrors = true;
+ }
+
+ private static string BuildConnectionString()
+ {
+ var connectionString = ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString;
+ int startIndex;
+ int endIndex;
+ string databaseName = ExtractDatabaseNameFromConnectionString(connectionString, out startIndex, out endIndex);
+ if (databaseName == "*")
+ {
+ databaseName = ExtractDatabaseNameFromRequestPath(HttpContext.Current.Request.Path);
+ if (!string.IsNullOrEmpty(databaseName))
+ {
+ connectionString = connectionString.Substring(0, startIndex) + databaseName + connectionString.Substring(endIndex);
+ }
+ }
+ return connectionString;
+ }
+
+ private static string ExtractDatabaseNameFromConnectionString(string connectionString, out int startIndex, out int endIndex)
+ {
+ startIndex = -1;
+ endIndex = -1;
+ var hostIndex = connectionString.IndexOf("//");
+ if (hostIndex > 0)
+ {
+ startIndex = connectionString.IndexOf("/", hostIndex + 2) + 1;
+ endIndex = connectionString.IndexOf("?", startIndex);
+ if (startIndex > 0)
+ {
+ if (endIndex > 0)
+ return connectionString.Substring(startIndex, endIndex - startIndex);
+ else
+ return connectionString.Substring(startIndex);
+ }
+ }
+ return string.Empty;
+ }
+
+ private static string ExtractDatabaseNameFromRequestPath(string requestPath)
+ {
+ if (requestPath.StartsWith("/"))
+ {
+ var startIndex = 1;
+ var endIndex = requestPath.IndexOf("/", 1);
+ if (endIndex > 0)
+ {
+ return requestPath.Substring(startIndex, endIndex - startIndex);
+ }
+ }
+ return string.Empty;
+ }
+ }
+}
@@ -1,3 +0,0 @@
-
-
-<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="Mongo.DataService.MongOData" %>
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data.Services;
-using System.Data.Services.Common;
-using Mongo.Context;
-using Mongo.Context.Queryable;
-
-namespace Mongo.DataService
-{
- public class MongOData : MongoQueryableDataService
- {
- public MongOData()
- : base(ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString)
- {
- }
-
- public static void InitializeService(DataServiceConfiguration config)
- {
- config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
- config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
- config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
- config.DataServiceBehavior.AcceptCountRequests = true;
- config.DataServiceBehavior.AcceptProjectionRequests = true;
- config.UseVerboseErrors = true;
- }
- }
-}
@@ -10,8 +10,8 @@
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Mongo.Service</RootNamespace>
- <AssemblyName>Mongo.Service</AssemblyName>
+ <RootNamespace>Mongo.DataService</RootNamespace>
+ <AssemblyName>Mongo.DataService</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<UseIISExpress>false</UseIISExpress>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
@@ -41,6 +41,7 @@
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.Services" />
<Reference Include="System.Data.Services.Client" />
+ <Reference Include="System.ServiceModel.Activation" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
@@ -60,7 +61,7 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
- <Content Include="MongOData.svc" />
+ <Content Include="Global.asax" />
<Content Include="Web.config" />
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
@@ -73,9 +74,10 @@
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
- <Compile Include="MongOData.svc.cs">
- <DependentUpon>MongOData.svc</DependentUpon>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
</Compile>
+ <Compile Include="MongOData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -95,9 +97,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <Content Include="..\ConnectionStrings.config">
- <Link>ConnectionStrings.config</Link>
- </Content>
+ <Content Include="ConnectionStrings.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

0 comments on commit 3496415

Please sign in to comment.