{"action":"created","issue":{"url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/1611","repository_url":"https://api.github.com/repos/AutoMapper/AutoMapper","labels_url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/1611/labels{/name}","comments_url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/1611/comments","events_url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/1611/events","html_url":"https://github.com/AutoMapper/AutoMapper/issues/1611","id":170463158,"number":1611,"title":"Unexpected behavior mapping null properties of interfaces","user":{"login":"Kchymet","id":3494517,"avatar_url":"https://avatars.githubusercontent.com/u/3494517?v=3","gravatar_id":"","url":"https://api.github.com/users/Kchymet","html_url":"https://github.com/Kchymet","followers_url":"https://api.github.com/users/Kchymet/followers","following_url":"https://api.github.com/users/Kchymet/following{/other_user}","gists_url":"https://api.github.com/users/Kchymet/gists{/gist_id}","starred_url":"https://api.github.com/users/Kchymet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kchymet/subscriptions","organizations_url":"https://api.github.com/users/Kchymet/orgs","repos_url":"https://api.github.com/users/Kchymet/repos","events_url":"https://api.github.com/users/Kchymet/events{/privacy}","received_events_url":"https://api.github.com/users/Kchymet/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-08-10T16:40:55Z","updated_at":"2016-08-17T17:57:29Z","closed_at":"2016-08-17T17:00:46Z","body":"I've been having some trouble mapping properties. Given the following classes/interfaces, the Metadata property doesn't seem to be mapping correctly (DocumentContents behaves as expected):\r\n```csharp\r\npublic interface ISourceDocument {\r\n    ISourceDocumentMetadata Metadata { get; set; }\r\n    string DocumentContents { get; set; }\r\n}\r\npublic class SourceDocument : ISourceDocument {\r\n    public ISourceDocumentMetadata Metadata { get; set; }\r\n    public string DocumentContents { get; set; }\r\n}\r\npublic class TargetDocument {\r\n    public TargetDocumentMetadata Metadata { get; set; }\r\n    public string DocumentContents { get; set; }\r\n}\r\n\r\npublic interface ISourceDocumentMetadata {}\r\npublic class SourceDocumentMetadata : ISourceDocumentMetadata {}\r\npublic class TargetDocumentMetadata { }\r\n```\r\n\r\nI wrote some tests to try and see when the unexpected mapping happens. Oddly enough, it only seems to happen mapping FROM an interface with an interface property. Mapping TO an interface (either with concrete types or proxies) works as expected. The first 2 tests here fail, the second 2 tests pass:\r\n```csharp\r\n// the first 3 assertions fail here\r\npublic void MapsNullPropertyToNull() {\r\n    var config = new MapperConfiguration(cfg => {\r\n        // map straight from interface\r\n        cfg.AllowNullCollections = true;\r\n        cfg.AllowNullDestinationValues = true;\r\n        cfg.CreateMap<ISourceDocument, TargetDocument>();\r\n        cfg.CreateMap<ISourceDocumentMetadata, TargetDocumentMetadata>();\r\n        cfg.CreateMap<SourceDocument, TargetDocument>();\r\n        cfg.CreateMap<SourceDocumentMetadata, TargetDocumentMetadata>();\r\n    });\r\n    var mapper = config.CreateMapper();\r\n    var doc = new SourceDocument {\r\n        Metadata = null,\r\n        DocumentContents = null\r\n    };\r\n    var mapped1 = mapper.Map<ISourceDocument, TargetDocument>(doc);\r\n    var mapped2 = mapper.Map<SourceDocument, TargetDocument>(doc);\r\n    var mapped3 = mapper.Map<TargetDocument>(doc);\r\n\r\n    Assert.IsNull(mapped1.DocumentContents);\r\n    Assert.IsNull(mapped2.DocumentContents);\r\n    Assert.IsNull(mapped3.DocumentContents);\r\n    Assert.IsNull(mapped1.Metadata);\r\n    Assert.IsNull(mapped2.Metadata);\r\n    Assert.IsNull(mapped3.Metadata);\r\n}\r\n\r\n// first 3 assertions fail here\r\npublic void MapsNullPropertyToNull2() { \r\n    var config = new MapperConfiguration(cfg => {\r\n        // using includes\r\n        cfg.AllowNullCollections = true;\r\n        cfg.AllowNullDestinationValues = true;\r\n        cfg.CreateMap<ISourceDocument, TargetDocument>()\r\n            .Include<SourceDocument, TargetDocument>();\r\n        cfg.CreateMap<ISourceDocumentMetadata, TargetDocumentMetadata>()\r\n            .Include<SourceDocumentMetadata, TargetDocumentMetadata>();\r\n        cfg.CreateMap<SourceDocument, TargetDocument>();\r\n        cfg.CreateMap<SourceDocumentMetadata, TargetDocumentMetadata>();\r\n    });\r\n    var mapper = config.CreateMapper();\r\n    var doc = new SourceDocument {\r\n        Metadata = null,\r\n        DocumentContents = null\r\n    };\r\n    var mapped1 = mapper.Map<ISourceDocument, TargetDocument>(doc);\r\n    var mapped2 = mapper.Map<SourceDocument, TargetDocument>(doc);\r\n    var mapped3 = mapper.Map<TargetDocument>(doc);\r\n\r\n    Assert.IsNull(mapped1.DocumentContents);\r\n    Assert.IsNull(mapped2.DocumentContents);\r\n    Assert.IsNull(mapped3.DocumentContents);\r\n    Assert.IsNull(mapped1.Metadata);\r\n    Assert.IsNull(mapped2.Metadata);\r\n    Assert.IsNull(mapped3.Metadata);\r\n}\r\n\r\n// all assertions PASS here\r\npublic void MapsNullPropertyToNull3() { \r\n    var config = new MapperConfiguration(cfg => {\r\n        // mapping to interface with concrete types\r\n        cfg.AllowNullCollections = true;\r\n        cfg.AllowNullDestinationValues = true;\r\n        cfg.CreateMap<TargetDocument, ISourceDocument>().As<SourceDocument>();\r\n        cfg.CreateMap<TargetDocumentMetadata, ISourceDocumentMetadata>().As<SourceDocumentMetadata>();\r\n        cfg.CreateMap<TargetDocument, SourceDocument>();\r\n        cfg.CreateMap<TargetDocumentMetadata, SourceDocumentMetadata>();\r\n    });\r\n    var mapper = config.CreateMapper();\r\n    var doc = new TargetDocument {\r\n        Metadata = null,\r\n        DocumentContents = null\r\n    };\r\n    var mapped1 = mapper.Map<TargetDocument, ISourceDocument>(doc);\r\n    var mapped2 = mapper.Map<TargetDocument, SourceDocument>(doc);\r\n    var mapped3 = mapper.Map<ISourceDocument>(doc);\r\n    var mapped4 = mapper.Map<SourceDocument>(doc);\r\n\r\n    Assert.IsNull(mapped1.DocumentContents);\r\n    Assert.IsNull(mapped2.DocumentContents);\r\n    Assert.IsNull(mapped3.DocumentContents);\r\n    Assert.IsNull(mapped4.DocumentContents);\r\n    Assert.IsNull(mapped1.Metadata);\r\n    Assert.IsNull(mapped2.Metadata);\r\n    Assert.IsNull(mapped3.Metadata);\r\n    Assert.IsNull(mapped4.Metadata);\r\n}\r\n\r\n// all assertions PASS here\r\npublic void MapsNullPropertyToNull4() { \r\n    var config = new MapperConfiguration(cfg => {\r\n        // mapping to interface using proxies\r\n        cfg.AllowNullCollections = true;\r\n        cfg.AllowNullDestinationValues = true;\r\n        cfg.CreateMap<TargetDocument, ISourceDocument>();\r\n        cfg.CreateMap<TargetDocumentMetadata, ISourceDocumentMetadata>();\r\n        cfg.CreateMap<TargetDocument, SourceDocument>();\r\n        cfg.CreateMap<TargetDocumentMetadata, SourceDocumentMetadata>();\r\n    });\r\n    var mapper = config.CreateMapper();\r\n    var doc = new TargetDocument {\r\n        Metadata = null,\r\n        DocumentContents = null\r\n    };\r\n    var mapped1 = mapper.Map<TargetDocument, ISourceDocument>(doc);\r\n    var mapped2 = mapper.Map<TargetDocument, SourceDocument>(doc);\r\n    var mapped3 = mapper.Map<ISourceDocument>(doc);\r\n    var mapped4 = mapper.Map<SourceDocument>(doc);\r\n\r\n    Assert.IsNull(mapped1.DocumentContents);\r\n    Assert.IsNull(mapped2.DocumentContents);\r\n    Assert.IsNull(mapped3.DocumentContents);\r\n    Assert.IsNull(mapped4.DocumentContents);\r\n    Assert.IsNull(mapped1.Metadata);\r\n    Assert.IsNull(mapped2.Metadata);\r\n    Assert.IsNull(mapped3.Metadata);\r\n    Assert.IsNull(mapped4.Metadata);\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/comments/240493651","html_url":"https://github.com/AutoMapper/AutoMapper/issues/1611#issuecomment-240493651","issue_url":"https://api.github.com/repos/AutoMapper/AutoMapper/issues/1611","id":240493651,"user":{"login":"jbogard","id":104498,"avatar_url":"https://avatars.githubusercontent.com/u/104498?v=3","gravatar_id":"","url":"https://api.github.com/users/jbogard","html_url":"https://github.com/jbogard","followers_url":"https://api.github.com/users/jbogard/followers","following_url":"https://api.github.com/users/jbogard/following{/other_user}","gists_url":"https://api.github.com/users/jbogard/gists{/gist_id}","starred_url":"https://api.github.com/users/jbogard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbogard/subscriptions","organizations_url":"https://api.github.com/users/jbogard/orgs","repos_url":"https://api.github.com/users/jbogard/repos","events_url":"https://api.github.com/users/jbogard/events{/privacy}","received_events_url":"https://api.github.com/users/jbogard/received_events","type":"User","site_admin":false},"created_at":"2016-08-17T17:57:28Z","updated_at":"2016-08-17T17:57:28Z","body":"Also, 5.1.1 is available on NuGet.\n\nOn Wed, Aug 17, 2016 at 12:00 PM, Kyle Chynoweth <notifications@github.com>\nwrote:\n\n> Closed #1611 <https://github.com/AutoMapper/AutoMapper/issues/1611>.\n>\n> —\n> You are receiving this because you are subscribed to this thread.\n> Reply to this email directly, view it on GitHub\n> <https://github.com/AutoMapper/AutoMapper/issues/1611#event-758790622>,\n> or mute the thread\n> <https://github.com/notifications/unsubscribe-auth/AAGYMm0qUwojIJal0YFug6V4YjN_ClY6ks5qgz4-gaJpZM4JhVxI>\n> .\n>\n"}}
{"actor":{"display_login":"jbogard"}}