Permalink
Browse files

refactoring to support flexible data service strategy and incorporate…

…d service operation discovery.
  • Loading branch information...
1 parent afe9090 commit 0272f4d9984e130d4fbb94d983cb5dbdb8042cae @craiggwilson committed Aug 30, 2012
@@ -7,6 +7,7 @@
using System.Web;
using MongoDB.Driver;
using MongoDB.OData.SampleModels.Blog;
+using MongoDB.OData.Typed;
namespace MongoDB.OData.SampleHost
{
@@ -33,11 +34,6 @@ public static void InitializeService(DataServiceConfiguration config)
config.UseVerboseErrors = true;
}
- protected override BlogEntities CreateDataSource(MongoServer server)
- {
- return new BlogEntities();
- }
-
protected override MongoServer CreateMongoServer()
{
var server = MongoServer.Create();
@@ -1,15 +1,12 @@
-using System;
+using MongoDB.Bson.Serialization;
+using MongoDB.Driver;
+using MongoDB.Driver.Linq;
+using MongoDB.OData.SampleModels.HumanResources;
+using System;
using System.Collections.Generic;
using System.Data.Services;
-using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
-using System.Web;
-using MongoDB.Bson.Serialization;
-using MongoDB.Driver;
-using MongoDB.Driver.Linq;
-using MongoDB.OData.SampleModels.HumanResources;
-using System.Data.Services.Providers;
namespace MongoDB.OData.SampleHost
{
@@ -55,6 +52,7 @@ public static void InitializeService(DataServiceConfiguration config)
{
Configure(config);
config.SetEntitySetAccessRule("*", EntitySetRights.All);
+ config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
config.UseVerboseErrors = true;
}
@@ -11,71 +11,64 @@
namespace MongoDB.OData.UnitTests
{
[TestFixture]
- internal class When_mapping_a_hierarchy : Specification<TypedMetadataBuilder>
+ internal class When_mapping_a_hierarchy : Specification<TypedMetadata>
{
- private IDataServiceMetadataProvider _metadata;
-
- protected override TypedMetadataBuilder EstablishContext()
- {
- return new TypedMetadataBuilder(typeof(Hierarchy));
- }
-
- protected override void Because()
+ protected override TypedMetadata EstablishContext()
{
- _metadata = Subject.BuildMetadata();
+ return new TypedMetadataBuilder<Hierarchy>().BuildMetadata();
}
[Test]
public void should_add_only_1_resource_set()
{
- _metadata.ResourceSets.Count().Should().Be(1);
+ Subject.ResourceSets.Count().Should().Be(1);
}
[Test]
public void should_map_the_resource_set()
{
- var set = _metadata.ResourceSets.Single();
+ var set = Subject.ResourceSets.Single();
set.ResourceType.InstanceType.Should().Be(typeof(Person));
set.ResourceType.IsAbstract.Should().BeTrue();
}
[Test]
public void should_recognize_the_derived_types()
{
- var personType = _metadata.Types.Single(x => x.InstanceType == typeof(Person));
- _metadata.HasDerivedTypes(personType).Should().BeTrue();
- var derivedTypes = _metadata.GetDerivedTypes(personType);
+ var personType = Subject.Types.Single(x => x.InstanceType == typeof(Person));
+ Subject.HasDerivedTypes(personType).Should().BeTrue();
+ var derivedTypes = Subject.GetDerivedTypes(personType);
derivedTypes.Count().Should().Be(4);
var spouseType = derivedTypes.Single(x => x.InstanceType == typeof(Spouse));
- _metadata.HasDerivedTypes(spouseType).Should().BeFalse();
+ Subject.HasDerivedTypes(spouseType).Should().BeFalse();
var employeeType = derivedTypes.Single(x => x.InstanceType == typeof(Employee));
- _metadata.HasDerivedTypes(employeeType).Should().BeTrue();
- derivedTypes = _metadata.GetDerivedTypes(employeeType);
+ Subject.HasDerivedTypes(employeeType).Should().BeTrue();
+ derivedTypes = Subject.GetDerivedTypes(employeeType);
derivedTypes.Count().Should().Be(2);
var managerType = derivedTypes.Single(x => x.InstanceType == typeof(Manager));
- _metadata.HasDerivedTypes(managerType).Should().BeFalse();
+ Subject.HasDerivedTypes(managerType).Should().BeFalse();
var contractorType = derivedTypes.Single(x => x.InstanceType == typeof(Contractor));
- _metadata.HasDerivedTypes(contractorType).Should().BeFalse();
+ Subject.HasDerivedTypes(contractorType).Should().BeFalse();
- var personRefType = _metadata.Types.Single(x => x.InstanceType == typeof(PersonRef));
- _metadata.HasDerivedTypes(personRefType).Should().BeTrue();
- derivedTypes = _metadata.GetDerivedTypes(personRefType);
+ var personRefType = Subject.Types.Single(x => x.InstanceType == typeof(PersonRef));
+ Subject.HasDerivedTypes(personRefType).Should().BeTrue();
+ derivedTypes = Subject.GetDerivedTypes(personRefType);
derivedTypes.Count().Should().Be(1);
var spouseRefType = derivedTypes.Single(x => x.InstanceType == typeof(SpouseRef));
- _metadata.HasDerivedTypes(spouseRefType).Should().BeFalse();
+ Subject.HasDerivedTypes(spouseRefType).Should().BeFalse();
}
[Test]
public void should_map_each_type_correctly()
{
- _metadata.Types.Count().Should().Be(8);
+ Subject.Types.Count().Should().Be(8);
- var personType = _metadata.Types.Single(x => x.InstanceType == typeof(Person));
+ var personType = Subject.Types.Single(x => x.InstanceType == typeof(Person));
personType.IsReadOnly.Should().BeTrue();
personType.BaseType.Should().BeNull();
personType.KeyProperties.Count.Should().Be(1);
@@ -85,7 +78,7 @@ public void should_map_each_type_correctly()
personProperties.Should().Contain(x => x.Name == "Id");
personProperties.Should().Contain(x => x.Name == "Name");
- var employeeType = _metadata.Types.Single(x => x.InstanceType == typeof(Employee));
+ var employeeType = Subject.Types.Single(x => x.InstanceType == typeof(Employee));
employeeType.IsReadOnly.Should().BeTrue();
employeeType.BaseType.Should().Be(personType);
var employeeProperties = employeeType.PropertiesDeclaredOnThisType;
@@ -94,28 +87,28 @@ public void should_map_each_type_correctly()
employeeProperties.Should().Contain(x => x.Name == "Salary");
employeeProperties.Should().Contain(x => x.Name == "Spouse");
- var spouseType = _metadata.Types.Single(x => x.InstanceType == typeof(Spouse));
+ var spouseType = Subject.Types.Single(x => x.InstanceType == typeof(Spouse));
spouseType.IsReadOnly.Should().BeTrue();
spouseType.BaseType.Should().Be(personType);
var spouseProperties = spouseType.PropertiesDeclaredOnThisType;
spouseProperties.Count.Should().Be(1);
spouseProperties.Should().Contain(x => x.Name == "SpousesId");
- var managerType = _metadata.Types.Single(x => x.InstanceType == typeof(Manager));
+ var managerType = Subject.Types.Single(x => x.InstanceType == typeof(Manager));
managerType.IsReadOnly.Should().BeTrue();
managerType.BaseType.Should().Be(employeeType);
var managerProperties = managerType.PropertiesDeclaredOnThisType;
managerProperties.Count.Should().Be(1);
managerProperties.Should().Contain(x => x.Name == "Employees");
- var contractorType = _metadata.Types.Single(x => x.InstanceType == typeof(Contractor));
+ var contractorType = Subject.Types.Single(x => x.InstanceType == typeof(Contractor));
contractorType.IsReadOnly.Should().BeTrue();
contractorType.BaseType.Should().Be(employeeType);
var contractorProperties = contractorType.PropertiesDeclaredOnThisType;
contractorProperties.Count.Should().Be(1);
contractorProperties.Should().Contain(x => x.Name == "Address");
- var nameType = _metadata.Types.Single(x => x.InstanceType == typeof(Name));
+ var nameType = Subject.Types.Single(x => x.InstanceType == typeof(Name));
nameType.IsReadOnly.Should().BeTrue();
nameType.BaseType.Should().BeNull();
nameType.KeyProperties.Count.Should().Be(0);
@@ -124,7 +117,7 @@ public void should_map_each_type_correctly()
nameProperties.Should().Contain(x => x.Name == "First");
nameProperties.Should().Contain(x => x.Name == "Last");
- var personRefType = _metadata.Types.Single(x => x.InstanceType == typeof(PersonRef));
+ var personRefType = Subject.Types.Single(x => x.InstanceType == typeof(PersonRef));
personRefType.IsReadOnly.Should().BeTrue();
personRefType.BaseType.Should().BeNull();
personRefType.KeyProperties.Count.Should().Be(0);
@@ -133,7 +126,7 @@ public void should_map_each_type_correctly()
personRefProperties.Should().Contain(x => x.Name == "Id");
personRefProperties.Should().Contain(x => x.Name == "Name");
- var spouseRefType = _metadata.Types.Single(x => x.InstanceType == typeof(SpouseRef));
+ var spouseRefType = Subject.Types.Single(x => x.InstanceType == typeof(SpouseRef));
spouseRefType.IsReadOnly.Should().BeTrue();
spouseRefType.BaseType.Should().Be(personRefType);
var spouseRefProperties = spouseRefType.PropertiesDeclaredOnThisType;
@@ -57,6 +57,8 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Spatial, Version=5.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\System.Spatial.5.0.1\lib\net40\System.Spatial.dll</HintPath>
@@ -70,6 +72,7 @@
<ItemGroup>
<Compile Include="MongoCollectionAttribute.cs" />
<Compile Include="MongoDatabaseAttribute.cs" />
+ <Compile Include="Typed\TypedDataSource.cs" />
<Compile Include="Typed\TypedMetadataBuilder.cs" />
<Compile Include="Typed\TypedResourceSetAnnotation.cs" />
<Compile Include="Typed\TypedMetadata.cs" />
@@ -2,11 +2,12 @@
using MongoDB.OData.Typed;
using System;
using System.Data.Services;
+using System.Data.Services.Common;
using System.Data.Services.Providers;
namespace MongoDB.OData
{
- public abstract class MongoDataService<T> : DataService<T>, IServiceProvider
+ public abstract class MongoDataService<T> : DataService<TypedDataSource>, IServiceProvider
{
private static object _metadataLock = new object();
private static TypedMetadata _metadata;
@@ -15,7 +16,7 @@ protected static void Configure(DataServiceConfiguration config)
{
config.DataServiceBehavior.AcceptProjectionRequests = false;
config.DataServiceBehavior.AcceptSpatialLiteralsInQuery = false;
- config.DataServiceBehavior.MaxProtocolVersion = System.Data.Services.Common.DataServiceProtocolVersion.V3;
+ config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
public object GetService(Type serviceType)
@@ -34,15 +35,16 @@ public object GetService(Type serviceType)
}
}
- protected sealed override T CreateDataSource()
+ protected sealed override TypedDataSource CreateDataSource()
{
var server = CreateMongoServer();
- var dataSource = CreateDataSource(server);
- InitializeDataSource(server, dataSource);
+ var dataContext = CreateDataContext(server);
+ var dataSource = new TypedDataSource(server, dataContext);
+ InitializeDataContext(dataSource);
return dataSource;
}
- protected virtual T CreateDataSource(MongoServer server)
+ protected virtual T CreateDataContext(MongoServer server)
{
var ctor = typeof(T).GetConstructor(new[] { typeof(MongoServer) });
@@ -58,7 +60,7 @@ protected virtual T CreateDataSource(MongoServer server)
return (T)ctor.Invoke(new object[0]);
}
- throw new InvalidOperationException(string.Format("Either overload the CreateDataSource(MongoServer) method or ensure that {0} has an empty ctor or a ctor that take a single MongoServer parameter.", typeof(T)));
+ throw new InvalidOperationException(string.Format("Either overload the CreateDataContext(MongoServer) method or ensure that {0} has an empty ctor or a ctor that take a single MongoServer parameter.", typeof(T)));
}
protected abstract MongoServer CreateMongoServer();
@@ -71,8 +73,8 @@ private TypedMetadata GetMetadata()
// {
// if (_metadataProvider == null)
// {
- var builder = new TypedMetadataBuilder(typeof(T));
- _metadata = builder.BuildMetadata();
+ var builder = new TypedMetadataBuilder<T>();
+ _metadata = builder.BuildMetadata();
// }
// }
//}
@@ -85,13 +87,13 @@ private TypedQueryProvider GetQueryProvider()
return new TypedQueryProvider(GetMetadata());
}
- private void InitializeDataSource(MongoServer server, T dataSource)
+ private void InitializeDataContext(TypedDataSource dataSource)
{
var metadata = GetMetadata();
foreach(var resourceSet in metadata.ResourceSets)
{
var annotation = (TypedResourceSetAnnotation)resourceSet.CustomState;
- annotation.Setter(dataSource, server);
+ annotation.SetDataContext(dataSource);
}
}
}
@@ -0,0 +1,17 @@
+using MongoDB.Driver;
+
+namespace MongoDB.OData.Typed
+{
+ public sealed class TypedDataSource
+ {
+ public object DataContext { get; private set; }
+
+ public MongoServer Server { get; private set; }
+
+ public TypedDataSource(MongoServer server, object dataContext)
+ {
+ Server = server;
+ DataContext = dataContext;
+ }
+ }
+}
@@ -11,6 +11,7 @@ internal class TypedMetadata : IDataServiceMetadataProvider
private readonly Dictionary<string, ResourceType> _types;
private readonly Dictionary<string, ResourceType> _qualifiedTypes;
private readonly Dictionary<ResourceType, List<ResourceType>> _derivedTypes;
+ private readonly Dictionary<string, ServiceOperation> _serviceOperations;
public string ContainerName { get; private set; }
@@ -23,22 +24,23 @@ public IEnumerable<ResourceSet> ResourceSets
public IEnumerable<ServiceOperation> ServiceOperations
{
- get { yield break; }
+ get { return _serviceOperations.Values; }
}
public IEnumerable<ResourceType> Types
{
get { return _types.Values; }
}
- public TypedMetadata(string containerNamespace, string containerName, IEnumerable<ResourceSet> resourceSets, IEnumerable<ResourceType> resourceTypes)
+ public TypedMetadata(string containerNamespace, string containerName, IEnumerable<ResourceSet> resourceSets, IEnumerable<ResourceType> resourceTypes, IEnumerable<ServiceOperation> serviceOperations)
{
ContainerNamespace = containerNamespace ?? "MongoDB";
ContainerName = containerName ?? "Database";
- _sets = resourceSets.ToDictionary(x => x.Name, x => x);
- _types = resourceTypes.ToDictionary(x => x.Name, x => x);
- _qualifiedTypes = resourceTypes.ToDictionary(x => x.FullName, x => x);
+ _sets = resourceSets.ToDictionary(x => x.Name);
+ _types = resourceTypes.ToDictionary(x => x.Name);
+ _qualifiedTypes = resourceTypes.ToDictionary(x => x.FullName);
+ _serviceOperations = serviceOperations.ToDictionary(x => x.Name);
_derivedTypes = new Dictionary<ResourceType, List<ResourceType>>();
foreach (var type in resourceTypes.Where(t => t.BaseType != null))
@@ -99,8 +101,7 @@ public bool TryResolveResourceType(string name, out ResourceType resourceType)
public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
{
- serviceOperation = null;
- return false;
+ return _serviceOperations.TryGetValue(name, out serviceOperation);
}
}
}
Oops, something went wrong.

0 comments on commit 0272f4d

Please sign in to comment.