From c42d46fb4cf59fbb749bb54dca153059659cc0b5 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 9 Aug 2016 21:35:30 +1200 Subject: [PATCH] -Improved Autofac sample to resolve contract from Autofac --- .../DeserializeWithDependencyInjection.cs | 26 ++++++- .../Serialization/DependencyInjectionTests.cs | 69 ++++++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithDependencyInjection.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithDependencyInjection.cs index 0fcafd38..0ba41418 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithDependencyInjection.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithDependencyInjection.cs @@ -39,6 +39,8 @@ using System.Runtime.Serialization; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using Autofac; +using Autofac.Core; +using Autofac.Core.Activators.Reflection; using Newtonsoft.Json.Tests.Serialization; using LogService = Newtonsoft.Json.Tests.Serialization.LogManager; @@ -59,15 +61,33 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer protected override JsonObjectContract CreateObjectContract(Type objectType) { - JsonObjectContract contract = base.CreateObjectContract(objectType); - // use Autofac to create types that have been registered with it if (_container.IsRegistered(objectType)) { + JsonObjectContract contract = ResolveContact(objectType); contract.DefaultCreator = () => _container.Resolve(objectType); + + return contract; } - return contract; + return base.CreateObjectContract(objectType); + } + + private JsonObjectContract ResolveContact(Type objectType) + { + // attempt to create the contact from the resolved type + IComponentRegistration registration; + if (_container.ComponentRegistry.TryGetRegistration(new TypedService(objectType), out registration)) + { + Type viewType = (registration.Activator as ReflectionActivator)?.LimitType; + if (viewType != null) + { + return base.CreateObjectContract(viewType); + } + } + + // fall back to using the registered type + return base.CreateObjectContract(objectType); } } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DependencyInjectionTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DependencyInjectionTests.cs index 2c790713..1888f9a3 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/DependencyInjectionTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/DependencyInjectionTests.cs @@ -30,8 +30,11 @@ using Newtonsoft.Json.Tests.TestObjects; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; +using Autofac.Core; +using Autofac.Core.Activators.Reflection; using Microsoft.FSharp.Collections; #if NETFX_CORE using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; @@ -126,6 +129,30 @@ namespace Newtonsoft.Json.Tests.Serialization } } +#if !NET20 + [DataContract] + public class User + { + [DataMember(Name = "first_name")] + public string FirstName { get; set; } + + [DataMember(Name = "company")] + public ICompany Company { get; set; } + } + + public interface ICompany + { + string CompanyName { get; set; } + } + + [DataContract] + public class Company : ICompany + { + [DataMember(Name = "company_name")] + public string CompanyName { get; set; } + } +#endif + public class AutofacContractResolver : DefaultContractResolver { private readonly IContainer _container; @@ -137,21 +164,57 @@ namespace Newtonsoft.Json.Tests.Serialization protected override JsonObjectContract CreateObjectContract(Type objectType) { - JsonObjectContract contract = base.CreateObjectContract(objectType); - // use Autofac to create types that have been registered with it if (_container.IsRegistered(objectType)) { + JsonObjectContract contract = ResolveContact(objectType); contract.DefaultCreator = () => _container.Resolve(objectType); + + return contract; } - return contract; + return base.CreateObjectContract(objectType); + } + + private JsonObjectContract ResolveContact(Type objectType) + { + // attempt to create the contact from the resolved type + IComponentRegistration registration; + if (_container.ComponentRegistry.TryGetRegistration(new TypedService(objectType), out registration)) + { + Type viewType = (registration.Activator as ReflectionActivator)?.LimitType; + if (viewType != null) + { + return base.CreateObjectContract(viewType); + } + } + + // fall back to using the registered type + return base.CreateObjectContract(objectType); } } [TestFixture] public class DependencyInjectionTests : TestFixtureBase { + [Test] + public void ResolveContractFromAutofac() + { + ContainerBuilder builder = new ContainerBuilder(); + builder.RegisterType().As(); + IContainer container = builder.Build(); + + AutofacContractResolver resolver = new AutofacContractResolver(container); + + User user = JsonConvert.DeserializeObject("{'company':{'company_name':'Company name!'}}", new JsonSerializerSettings + { + ContractResolver = resolver + + }); + + Assert.AreEqual("Company name!", user.Company.CompanyName); + } + [Test] public void CreateObjectWithParameters() {