Skip to content

Commit

Permalink
breeze.net - more inheritance + debug diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
jtraband committed Mar 14, 2014
1 parent 5d8f590 commit d4f94aa
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 77 deletions.
2 changes: 2 additions & 0 deletions Breeze.NetClient/BaseEntity.cs
@@ -1,10 +1,12 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Breeze.NetClient {

[DebuggerDisplay("{EntityAspect.EntityKey} - {EntityAspect.EntityState}")]
public abstract class BaseEntity : IEntity {

protected BaseEntity() {
Expand Down
2 changes: 2 additions & 0 deletions Breeze.NetClient/ComplexType.cs
@@ -1,10 +1,12 @@
using Breeze.Core;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;

namespace Breeze.NetClient {

[DebuggerDisplay("{Name}")]
public class ComplexType: StructuralType, IJsonSerializable {

public ComplexType() :base() {
Expand Down
16 changes: 0 additions & 16 deletions Breeze.NetClient/Core/TypeFns.cs
Expand Up @@ -148,22 +148,6 @@ public static class TypeFns {
return types;
}

/// <summary>
/// Returns a list of all of the types in one or more assemblies that implement a specific
/// interface or extend a specific class.
/// </summary>
/// <param name="type">Interface or base type</param>
/// <param name="assemblies"></param>
/// <returns></returns>
public static Type[] GetTypesImplementing(Type type, IEnumerable<Assembly> assemblies) {
if (assemblies == null) {
return new Type[0];
}
var validAssemblies = GetValidAssemblies(assemblies);
var result = validAssemblies.SelectMany(a => GetTypesImplementing(type, a)).ToArray();
return result;
}

internal static IEnumerable<Type> GetTypes(Assembly assembly) {
lock (__invalidAssemblies) {
if (__invalidAssemblies.Contains(assembly)) {
Expand Down
2 changes: 1 addition & 1 deletion Breeze.NetClient/CsdlMetadataProcessor.cs
Expand Up @@ -60,7 +60,7 @@ class CsdlMetadataProcessor {
var baseTypeName = baseTypeInfo.TypeName;
entityType.BaseTypeName = baseTypeName;
var baseEntityType = _metadataStore.GetEntityType(baseTypeName, true);
if (baseEntityType == null) {
if (baseEntityType != null) {
CompleteParseCsdlEntityType(entityType, csdlEntityType, baseEntityType);
} else {
List<DeferredTypeInfo> deferrals;
Expand Down
1 change: 1 addition & 0 deletions Breeze.NetClient/EntityKey.cs
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Breeze.NetClient {
Expand Down
2 changes: 2 additions & 0 deletions Breeze.NetClient/EntityType.cs
Expand Up @@ -2,10 +2,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;

namespace Breeze.NetClient {

[DebuggerDisplay("{Name}")]
public class EntityType : StructuralType, IJsonSerializable {

public EntityType() {
Expand Down
18 changes: 16 additions & 2 deletions Breeze.NetClient/JsonEntityConverter.cs
Expand Up @@ -71,8 +71,22 @@ public class JsonEntityConverter : JsonConverter {
return _refMap[refToken.Value<String>()];
}

var objectType = jsonContext.ObjectType;
var entityType = _metadataStore.GetEntityType(objectType);
EntityType entityType;
Type objectType;
JToken typeToken = null;
if (jObject.TryGetValue("$type", out typeToken)) {
var clrTypeName = typeToken.Value<String>();
var entityTypeName = StructuralType.ClrTypeNameToStructuralTypeName(clrTypeName);
entityType = _metadataStore.GetEntityType(entityTypeName);
objectType = entityType.ClrType;
if (!jsonContext.ObjectType.IsAssignableFrom(objectType)) {
throw new Exception("Unable to convert returned type: " + objectType.Name + " into type: " + jsonContext.ObjectType.Name);
}
jsonContext.ObjectType = objectType;
} else {
objectType = jsonContext.ObjectType;
entityType = _metadataStore.GetEntityType(objectType);
}

// an entity type
jsonContext.StructuralType = entityType;
Expand Down
34 changes: 24 additions & 10 deletions Breeze.NetClient/MetadataStore.cs
Expand Up @@ -17,9 +17,13 @@ public class MetadataStore : IJsonSerializable {

private MetadataStore() {
_clrTypeMap = new ClrTypeMap(this);
RegisterTypeDiscoveryAction(typeof(IEntity), (t) => _clrTypeMap.GetStructuralType(t));
RegisterTypeDiscoveryAction(typeof(IComplexObject), (t) => _clrTypeMap.GetStructuralType(t));
RegisterTypeDiscoveryAction(typeof(Validator), (t) => RegisterValidator(t));
RegisterTypeDiscoveryActionCore(typeof(IEntity), (t) => _clrTypeMap.GetStructuralType(t), false);
RegisterTypeDiscoveryActionCore(typeof(IComplexObject), (t) => _clrTypeMap.GetStructuralType(t), false);
RegisterTypeDiscoveryActionCore(typeof(Validator), (t) => RegisterValidator(t), true);
}

private bool NotThisAssembly(Assembly assembly) {
return (assembly != this.GetType().GetTypeInfo().Assembly);
}

// Explicit static constructor to tell C# compiler
Expand Down Expand Up @@ -87,11 +91,14 @@ public class MetadataStore : IJsonSerializable {
lock (_structuralTypes) {
var assemblies = assembliesToProbe.Except(_probedAssemblies).ToList();
if (assemblies.Any()) {
assemblies.ForEach(a => _probedAssemblies.Add(a));
_typeDiscoveryActions.ForEach(tpl => {
var type = tpl.Item1;
var action = tpl.Item2;
TypeFns.GetTypesImplementing(type, assemblies).ForEach(t => action(t));
assemblies.ForEach(asm => {
_probedAssemblies.Add(asm);
_typeDiscoveryActions.Where(tpl => tpl.Item3 == null || tpl.Item3(asm))
.ForEach(tpl => {
var type = tpl.Item1;
var action = tpl.Item2;
TypeFns.GetTypesImplementing(type, asm).ForEach(t => action(t));
});
});
return true;
} else {
Expand All @@ -101,7 +108,14 @@ public class MetadataStore : IJsonSerializable {
}

public void RegisterTypeDiscoveryAction(Type type, Action<Type> action) {
_typeDiscoveryActions.Add(Tuple.Create(type, action));
RegisterTypeDiscoveryActionCore(type, action, false);
}

private void RegisterTypeDiscoveryActionCore(Type type, Action<Type> action, bool includeThisAssembly) {
Func<Assembly, bool> shouldProcessAssembly = (a) => {
return includeThisAssembly ? true : a != this.GetType().GetTypeInfo().Assembly;
};
_typeDiscoveryActions.Add(Tuple.Create(type, action, shouldProcessAssembly));
}

public void RegisterTypeInitializer(Type type, Action<Object> action) {
Expand Down Expand Up @@ -639,7 +653,7 @@ private class TypePair {
// locked using _structuralTypes
private ClrTypeMap _clrTypeMap;
private HashSet<Assembly> _probedAssemblies = new HashSet<Assembly>();
private List<Tuple<Type, Action<Type>>> _typeDiscoveryActions = new List<Tuple<Type, Action<Type>>>();
private List<Tuple<Type, Action<Type>, Func<Assembly, bool>>> _typeDiscoveryActions = new List<Tuple<Type, Action<Type>, Func<Assembly, bool>>>();
private Dictionary<Type, Action<Object>> _typeInitializerMap = new Dictionary<Type, Action<object>>();
private StructuralTypeCollection _structuralTypes = new StructuralTypeCollection();
private Dictionary<String, String> _shortNameMap = new Dictionary<string, string>();
Expand Down
43 changes: 0 additions & 43 deletions Breeze.NetClient/SaveContext.cs

This file was deleted.

2 changes: 2 additions & 0 deletions Breeze.NetClient/StructuralType.cs
Expand Up @@ -49,9 +49,11 @@ public abstract class StructuralType {
}

public MetadataStore MetadataStore { get; internal set; }

public String Name {
get { return QualifyTypeName(ShortName, Namespace); }
}

public Type ClrType {
get {
if (_clrType == null) {
Expand Down
4 changes: 4 additions & 0 deletions Breeze.NetClient/_TODO.txt
@@ -1,4 +1,8 @@

- Add good message for AuthorizedThreadId check and how to turn it off for unit tests
- Add good message for structuralType not found messages and how to call ProbeAssemblies
- ProbeAssemblies should default to not searching Breeze.NEtClient.

- implement JsonResultsAdapter


4 changes: 4 additions & 0 deletions Test_NetClient/Breeze.NetClient.Test.csproj
Expand Up @@ -80,6 +80,10 @@
<Project>{54b1ce10-2847-4565-839a-26da3a51af38}</Project>
<Name>Breeze.NetClient</Name>
</ProjectReference>
<ProjectReference Include="..\_Internal\Model_Inheritance_NetClient\Model_Inheritance_NetClient.csproj">
<Project>{5b809bb6-85ef-4384-ba2b-54889617f76f}</Project>
<Name>Model_Inheritance_NetClient</Name>
</ProjectReference>
<ProjectReference Include="..\_Internal\Model_Northwind_NetClient\Model_Northwind_NetClient.csproj">
<Project>{afbede2c-1937-4a3a-88a1-046973d969e5}</Project>
<Name>Model_Northwind_NetClient</Name>
Expand Down
27 changes: 24 additions & 3 deletions Test_NetClient/InheritanceTests.cs
Expand Up @@ -6,6 +6,7 @@
using Breeze.NetClient;
using System.Collections.Generic;
using Foo;
using Inheritance.Models;

namespace Test_NetClient {

Expand All @@ -22,6 +23,8 @@ public class InheritanceTests {
}

public async Task<EntityManager> SetUpAsync() {
MetadataStore.Instance.ProbeAssemblies(typeof(CreditCardTPC).Assembly);

var serviceName = "http://localhost:7150/breeze/Inheritance/";

if (MetadataStore.Instance.EntityTypes.Count == 0) {
Expand All @@ -40,13 +43,31 @@ public class InheritanceTests {
}

[TestMethod]
public async Task SimpleQuery() {
public async Task SimpleTPH() {
await _emTask;
var q = new EntityQuery<Customer>();
var r = await QueryBillingBase<BillingDetailTPH>("BillingDetailTPH");
}


[TestMethod]
public async Task SimpleTPT() {
await _emTask;
var r = await QueryBillingBase<BillingDetailTPT>("BillingDetailTPT");
}

[TestMethod]
public async Task SimpleTPC() {
await _emTask;
var r = await QueryBillingBase<BillingDetailTPC>("BillingDetailTPC");
}


private async Task<IEnumerable<T>> QueryBillingBase<T>(String typeName) {
var q0 = new EntityQuery<T>(typeName + "s").With(_em1);
var r0 = await q0.Execute();
Assert.IsTrue(r0.Count() > 0);
Assert.IsTrue(r0.All(r => typeof(T).IsAssignableFrom(r.GetType())));
return r0;
}


}
Expand Down
2 changes: 1 addition & 1 deletion Test_NetClient/NamedQueryTests.cs
Expand Up @@ -31,7 +31,7 @@ public class NamedQueryTests {

public async Task<EntityManager> SetUpAsync() {
var serviceName = "http://localhost:7150/breeze/NorthwindIBModel/";
MetadataStore.Instance.ProbeAssemblies(new Assembly[] { typeof(Order).Assembly });
MetadataStore.Instance.ProbeAssemblies(typeof(Order).Assembly );
if (MetadataStore.Instance.EntityTypes.Count == 0) {
_em1 = new EntityManager(serviceName);
await _em1.FetchMetadata();
Expand Down
2 changes: 1 addition & 1 deletion Test_NetClient/SaveTests.cs
Expand Up @@ -31,7 +31,7 @@ public class SaveTests {

public async Task<EntityManager> SetUpAsync() {
var serviceName = "http://localhost:7150/breeze/NorthwindIBModel/";
MetadataStore.Instance.ProbeAssemblies(new Assembly[] { typeof(Order).Assembly });
MetadataStore.Instance.ProbeAssemblies(typeof(Order).Assembly);
if (MetadataStore.Instance.EntityTypes.Count == 0) {
_em1 = new EntityManager(serviceName);
await _em1.FetchMetadata();
Expand Down

0 comments on commit d4f94aa

Please sign in to comment.