See More

using System; using Autofac; using Autofac.Core; using JSONAPI.ActionFilters; using JSONAPI.Configuration; using JSONAPI.Core; using JSONAPI.Documents; using JSONAPI.Documents.Builders; using JSONAPI.Http; using JSONAPI.Json; using JSONAPI.QueryableTransformers; namespace JSONAPI.Autofac { public class JsonApiAutofacModule : Module { private readonly IJsonApiConfiguration _jsonApiConfiguration; internal JsonApiAutofacModule(IJsonApiConfiguration jsonApiConfiguration) { _jsonApiConfiguration = jsonApiConfiguration; } 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(resourceTypeRegistration.Type) .Keyed(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().SingleInstance(); builder.Register(c => { var context = c.Resolve(); Func factory = resourceTypeName => { var configuration = context.ResolveKeyed(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(parameters); }; return factory; }); builder.Register(c => { var context = c.Resolve(); Func factory = clrType => { var configuration = context.ResolveKeyed(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(parameters); }; return factory; }); builder.Register(c => { var context = c.Resolve(); Func factory = (resourceTypeName, relationshipName) => { var configuration = context.ResolveKeyed(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(parameters); }; return factory; }); builder.RegisterType().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().InstancePerRequest(); // Serialization builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); // Queryable transforms builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); // Document building builder.Register(c => _jsonApiConfiguration.LinkConventions).As().SingleInstance(); builder.RegisterType().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().SingleInstance(); builder.RegisterType().SingleInstance(); builder.RegisterType().As(); } } }