public void GetRegistrationForType_fails_when_getting_unregistered_type() { // Arrange var registry = new ResourceTypeRegistry(); // Act Action action = () => { registry.GetRegistrationForType(typeof(Post)); }; // Assert action.ShouldThrow<TypeRegistrationNotFoundException>().WithMessage("No type registration was found for the type \"Post\"."); }
public void GetRegistrationForType_returns_correct_value_for_registered_types() { // Arrange var mockPostRegistration = new Mock<IResourceTypeRegistration>(MockBehavior.Strict); mockPostRegistration.Setup(m => m.Type).Returns(typeof(Post)); mockPostRegistration.Setup(m => m.ResourceTypeName).Returns("posts"); var mockAuthorRegistration = new Mock<IResourceTypeRegistration>(MockBehavior.Strict); mockAuthorRegistration.Setup(m => m.Type).Returns(typeof(Author)); mockAuthorRegistration.Setup(m => m.ResourceTypeName).Returns("authors"); var registry = new ResourceTypeRegistry(); registry.AddRegistration(mockPostRegistration.Object); registry.AddRegistration(mockAuthorRegistration.Object); // Act var authorReg = registry.GetRegistrationForType(typeof(Author)); var postReg = registry.GetRegistrationForType(typeof(Post)); // Assert postReg.Should().BeSameAs(mockPostRegistration.Object); authorReg.Should().BeSameAs(mockAuthorRegistration.Object); }
public void GetRegistrationForType_gets_registration_for_closest_registered_base_type_for_unregistered_type() { // Arrange var mockPostRegistration = new Mock<IResourceTypeRegistration>(MockBehavior.Strict); mockPostRegistration.Setup(m => m.Type).Returns(typeof(Post)); mockPostRegistration.Setup(m => m.ResourceTypeName).Returns("posts"); var registry = new ResourceTypeRegistry(); registry.AddRegistration(mockPostRegistration.Object); // Act var registration = registry.GetRegistrationForType(typeof(DerivedPost)); // Assert registration.Type.Should().Be(typeof(Post)); }
protected override void Load(ContainerBuilder builder) { // Register resource types var registry = new ResourceTypeRegistry(); foreach (var resourceTypeConfiguration in _jsonApiConfiguration.ResourceTypeConfigurations) { var resourceTypeRegistration = resourceTypeConfiguration.BuildResourceTypeRegistration(); registry.AddRegistration(resourceTypeRegistration); var configuration = resourceTypeConfiguration; builder.Register(c => configuration) .Keyed<IResourceTypeConfiguration>(resourceTypeRegistration.Type) .Keyed<IResourceTypeConfiguration>(resourceTypeRegistration.ResourceTypeName) .SingleInstance(); if (resourceTypeConfiguration.DocumentMaterializerType != null) builder.RegisterType(resourceTypeConfiguration.DocumentMaterializerType); foreach (var relationship in resourceTypeRegistration.Relationships) { IResourceTypeRelationshipConfiguration relationshipConfiguration; if (resourceTypeConfiguration.RelationshipConfigurations .TryGetValue(relationship.Property.Name, out relationshipConfiguration)) { if (relationshipConfiguration.MaterializerType != null) { builder.RegisterType(relationshipConfiguration.MaterializerType); continue; } } // They didn't set an explicit materializer. See if they specified a factory for this resource type. if (configuration.RelatedResourceMaterializerTypeFactory == null) continue; var materializerType = configuration.RelatedResourceMaterializerTypeFactory(relationship); builder.RegisterType(materializerType); } } builder.Register(c => registry).As<IResourceTypeRegistry>().SingleInstance(); builder.Register(c => { var context = c.Resolve<IComponentContext>(); Func<string, IDocumentMaterializer> factory = resourceTypeName => { var configuration = context.ResolveKeyed<IResourceTypeConfiguration>(resourceTypeName); var registration = registry.GetRegistrationForResourceTypeName(resourceTypeName); var parameters = new Parameter[] { new TypedParameter(typeof (IResourceTypeRegistration), registration) }; if (configuration.DocumentMaterializerType != null) return (IDocumentMaterializer)context.Resolve(configuration.DocumentMaterializerType, parameters); return context.Resolve<IDocumentMaterializer>(parameters); }; return factory; }); builder.Register(c => { var context = c.Resolve<IComponentContext>(); Func<Type, IDocumentMaterializer> factory = clrType => { var configuration = context.ResolveKeyed<IResourceTypeConfiguration>(clrType); var registration = registry.GetRegistrationForType(clrType); var parameters = new Parameter[] { new TypedParameter(typeof(IResourceTypeRegistration), registration) }; if (configuration.DocumentMaterializerType != null) return (IDocumentMaterializer)context.Resolve(configuration.DocumentMaterializerType, parameters); return context.Resolve<IDocumentMaterializer>(parameters); }; return factory; }); builder.Register(c => { var context = c.Resolve<IComponentContext>(); Func<string, string, IRelatedResourceDocumentMaterializer> factory = (resourceTypeName, relationshipName) => { var configuration = context.ResolveKeyed<IResourceTypeConfiguration>(resourceTypeName); var registration = registry.GetRegistrationForResourceTypeName(resourceTypeName); var relationship = registration.GetFieldByName(relationshipName) as ResourceTypeRelationship; if (relationship == null) throw JsonApiException.CreateForNotFound( string.Format("No relationship `{0}` exists for the resource type `{1}`.", relationshipName, resourceTypeName)); var parameters = new Parameter[] { new TypedParameter(typeof(IResourceTypeRegistration), registration), new TypedParameter(typeof(ResourceTypeRelationship), relationship) }; // First, see if they have set an explicit materializer for this relationship IResourceTypeRelationshipConfiguration relationshipConfiguration; if (configuration.RelationshipConfigurations.TryGetValue(relationship.Property.Name, out relationshipConfiguration) && relationshipConfiguration.MaterializerType != null) return (IRelatedResourceDocumentMaterializer)context.Resolve(relationshipConfiguration.MaterializerType, parameters); // They didn't set an explicit materializer. See if they specified a factory for this resource type. if (configuration.RelatedResourceMaterializerTypeFactory != null) { var materializerType = configuration.RelatedResourceMaterializerTypeFactory(relationship); return (IRelatedResourceDocumentMaterializer)context.Resolve(materializerType, parameters); } return context.Resolve<IRelatedResourceDocumentMaterializer>(parameters); }; return factory; }); builder.RegisterType<JsonApiHttpConfiguration>().SingleInstance(); builder.RegisterType<BaseUrlService>().As<IBaseUrlService>().SingleInstance(); builder.RegisterType<DocumentMaterializerLocator>().As<IDocumentMaterializerLocator>().InstancePerRequest(); // Serialization builder.RegisterType<MetadataFormatter>().As<IMetadataFormatter>().SingleInstance(); builder.RegisterType<LinkFormatter>().As<ILinkFormatter>().SingleInstance(); builder.RegisterType<ResourceLinkageFormatter>().As<IResourceLinkageFormatter>().SingleInstance(); builder.RegisterType<RelationshipObjectFormatter>().As<IRelationshipObjectFormatter>().SingleInstance(); builder.RegisterType<ResourceObjectFormatter>().As<IResourceObjectFormatter>().SingleInstance(); builder.RegisterType<SingleResourceDocumentFormatter>().As<ISingleResourceDocumentFormatter>().SingleInstance(); builder.RegisterType<ResourceCollectionDocumentFormatter>().As<IResourceCollectionDocumentFormatter>().SingleInstance(); builder.RegisterType<ErrorFormatter>().As<IErrorFormatter>().SingleInstance(); builder.RegisterType<ErrorDocumentFormatter>().As<IErrorDocumentFormatter>().SingleInstance(); // Queryable transforms builder.RegisterType<SynchronousEnumerationTransformer>().As<IQueryableEnumerationTransformer>().SingleInstance(); builder.RegisterType<DefaultFilteringTransformer>().As<IQueryableFilteringTransformer>().SingleInstance(); builder.RegisterType<DefaultSortingTransformer>().As<IQueryableSortingTransformer>().SingleInstance(); builder.RegisterType<DefaultPaginationTransformer>().As<IQueryablePaginationTransformer>().SingleInstance(); // Document building builder.Register(c => _jsonApiConfiguration.LinkConventions).As<ILinkConventions>().SingleInstance(); builder.RegisterType<JsonApiFormatter>().SingleInstance(); builder.RegisterType<RegistryDrivenResourceCollectionDocumentBuilder>().As<IResourceCollectionDocumentBuilder>().SingleInstance(); builder.RegisterType<RegistryDrivenSingleResourceDocumentBuilder>().As<ISingleResourceDocumentBuilder>().SingleInstance(); builder.RegisterType<FallbackDocumentBuilder>().As<IFallbackDocumentBuilder>().SingleInstance(); builder.RegisterType<ErrorDocumentBuilder>().As<IErrorDocumentBuilder>().SingleInstance(); builder.RegisterType<FallbackDocumentBuilderAttribute>().SingleInstance(); builder.RegisterType<JsonApiExceptionFilterAttribute>().SingleInstance(); builder.RegisterType<DefaultQueryableResourceCollectionDocumentBuilder>().As<IQueryableResourceCollectionDocumentBuilder>(); }
public static void Configure(IContainer container, JsonApiConfiguration jsonApiConfiguration) { container.Configure(cfg => cfg.AddRegistry<JsonApiRegistry>()); var registry = new ResourceTypeRegistry(); foreach (var resourceTypeConfiguration in jsonApiConfiguration.ResourceTypeConfigurations) { var resourceTypeRegistration = resourceTypeConfiguration.BuildResourceTypeRegistration(); registry.AddRegistration(resourceTypeRegistration); var configuration = resourceTypeConfiguration; container.Configure(cfg => { cfg.For<IResourceTypeConfiguration>().Use(configuration).Named(resourceTypeRegistration.Type.FullName).Singleton(); cfg.For<IResourceTypeConfiguration>().Use(configuration).Named(resourceTypeRegistration.ResourceTypeName).Singleton(); }); if (resourceTypeConfiguration.DocumentMaterializerType != null) { container.Configure(cfg => cfg.For(resourceTypeConfiguration.DocumentMaterializerType)); } foreach (var relationship in resourceTypeRegistration.Relationships) { IResourceTypeRelationshipConfiguration relationshipConfiguration; if (resourceTypeConfiguration.RelationshipConfigurations .TryGetValue(relationship.Property.Name, out relationshipConfiguration)) { if (relationshipConfiguration.MaterializerType != null) { container.Configure(cfg => cfg.For(relationshipConfiguration.MaterializerType)); continue; } } // They didn't set an explicit materializer. See if they specified a factory for this resource type. if (configuration.RelatedResourceMaterializerTypeFactory == null) continue; var materializerType = configuration.RelatedResourceMaterializerTypeFactory(relationship); container.Configure(cfg => cfg.For(materializerType)); } } container.Configure(cfg => cfg.For<IResourceTypeRegistry>().Use(c => registry).Singleton()); container.Configure(cfg => { cfg.For<IDocumentMaterializerLocator>() .Use<DocumentMaterializerLocator>() .Ctor<Func<string, IDocumentMaterializer>>().Is(resourceTypeName => { var configuration = container.GetInstance<IResourceTypeConfiguration>(resourceTypeName); var registration = registry.GetRegistrationForResourceTypeName(resourceTypeName); var args = new ExplicitArguments(); args.Set<IResourceTypeRegistration>(registration); if (configuration.DocumentMaterializerType != null) return (IDocumentMaterializer) container.With(args).GetInstance(configuration.DocumentMaterializerType); return container.With(args).GetInstance<IDocumentMaterializer>(); }) .Ctor<Func<Type, IDocumentMaterializer>>().Is(type => { var configuration = container.GetInstance<IResourceTypeConfiguration>(type.FullName); var registration = registry.GetRegistrationForType(type); var args = new ExplicitArguments(); args.Set<IResourceTypeRegistration>(registration); if (configuration.DocumentMaterializerType != null) return (IDocumentMaterializer) container.With(args).GetInstance(configuration.DocumentMaterializerType); return container.With(args).GetInstance<IDocumentMaterializer>(); }) .Ctor<Func<string, string, IRelatedResourceDocumentMaterializer>>().Is((resourceTypeName, relationshipName) => { var configuration = container.GetInstance<IResourceTypeConfiguration>(resourceTypeName); var registration = registry.GetRegistrationForResourceTypeName(resourceTypeName); var relationship = registration.GetFieldByName(relationshipName) as ResourceTypeRelationship; if (relationship == null) throw JsonApiException.CreateForNotFound( string.Format("No relationship `{0}` exists for the resource type `{1}`.", relationshipName, resourceTypeName)); var args = new ExplicitArguments(); args.Set<IResourceTypeRegistration>(registration); args.Set<ResourceTypeRelationship>(relationship); // First, see if they have set an explicit materializer for this relationship IResourceTypeRelationshipConfiguration relationshipConfiguration; if (configuration.RelationshipConfigurations.TryGetValue(relationship.Property.Name, out relationshipConfiguration) && relationshipConfiguration.MaterializerType != null) return (IRelatedResourceDocumentMaterializer)container.With(args).GetInstance(relationshipConfiguration.MaterializerType); // They didn't set an explicit materializer. See if they specified a factory for this resource type. if (configuration.RelatedResourceMaterializerTypeFactory != null) { var materializerType = configuration.RelatedResourceMaterializerTypeFactory(relationship); return (IRelatedResourceDocumentMaterializer)container.With(args).GetInstance(materializerType); } return container.With(args).GetInstance<IRelatedResourceDocumentMaterializer>(); }); }); container.Configure(cfg => cfg.For<ILinkConventions>().Use(c => jsonApiConfiguration.LinkConventions).Singleton()); }