Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions AutoMapper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoMapper.UnitTests", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoMapper.IntegrationTests", "src\IntegrationTests\AutoMapper.IntegrationTests.csproj", "{24B47F4C-0035-4F29-AAD9-4C47E1AAD98E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoMapper.DI.Tests", "src\AutoMapper.Extensions.Microsoft.DependencyInjection.Tests\AutoMapper.DI.Tests.csproj", "{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp", "src\TestApp\TestApp.csproj", "{35CED3AE-B825-4703-992D-A58B5BE646DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -96,6 +100,38 @@ Global
{24B47F4C-0035-4F29-AAD9-4C47E1AAD98E}.Release|x64.Build.0 = Release|Any CPU
{24B47F4C-0035-4F29-AAD9-4C47E1AAD98E}.Release|x86.ActiveCfg = Release|Any CPU
{24B47F4C-0035-4F29-AAD9-4C47E1AAD98E}.Release|x86.Build.0 = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|ARM.Build.0 = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|x64.ActiveCfg = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|x64.Build.0 = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|x86.ActiveCfg = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Debug|x86.Build.0 = Debug|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|Any CPU.Build.0 = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|ARM.ActiveCfg = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|ARM.Build.0 = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|x64.ActiveCfg = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|x64.Build.0 = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|x86.ActiveCfg = Release|Any CPU
{BEBD620A-8BAA-463F-BE0F-8319AD3C1644}.Release|x86.Build.0 = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|ARM.Build.0 = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|x64.Build.0 = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|x86.ActiveCfg = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Debug|x86.Build.0 = Debug|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|Any CPU.Build.0 = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|ARM.ActiveCfg = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|ARM.Build.0 = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|x64.ActiveCfg = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|x64.Build.0 = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|x86.ActiveCfg = Release|Any CPU
{35CED3AE-B825-4703-992D-A58B5BE646DC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 2 additions & 0 deletions docs/13.0-Upgrade-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## AutoMapper now targets .Net 6

## `AddAutoMapper` is part of the core package and the DI package is discontinued

## `IMapper` has nullable annotations

Besides the build-time impact, there is also a behaviour change. Non-generic `Map` overloads require now either a destination type or a non-null destination object.
Expand Down
2 changes: 2 additions & 0 deletions docs/Dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

There is a [NuGet package](https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/) to be used with the default injection mechanism described [here](https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection) and used in [this project](https://github.com/jbogard/ContosoUniversityCore/blob/master/src/ContosoUniversityCore/Startup.cs).

Starting with version 13.0, `AddAutoMapper` is part of the core package and the DI package is discontinued.

You define the configuration using [profiles](Configuration.html#profile-instances). And then you let AutoMapper know in what assemblies are those profiles defined by calling the `IServiceCollection` extension method `AddAutoMapper` at startup:
```c#
services.AddAutoMapper(profileAssembly1, profileAssembly2 /*, ...*/);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Microsoft.Extensions.DependencyInjection;

namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests
{
using System;
using AutoMapper.Internal;
using Shouldly;
using Xunit;

public class AppDomainResolutionTests
{
private readonly IServiceProvider _provider;

public AppDomainResolutionTests()
{
IServiceCollection services = new ServiceCollection();
services.AddAutoMapper(typeof(AppDomainResolutionTests));
_provider = services.BuildServiceProvider();
}

[Fact]
public void ShouldResolveConfiguration()
{
_provider.GetService<IConfigurationProvider>().ShouldNotBeNull();
}

[Fact]
public void ShouldConfigureProfiles()
{
_provider.GetService<IConfigurationProvider>().Internal().GetAllTypeMaps().Count.ShouldBe(4);
}

[Fact]
public void ShouldResolveMapper()
{
_provider.GetService<IMapper>().ShouldNotBeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Microsoft.Extensions.DependencyInjection;

namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests
{
using System;
using System.Reflection;
using AutoMapper.Internal;
using Shouldly;
using Xunit;

public class AssemblyResolutionTests
{
private static readonly IServiceProvider _provider;

static AssemblyResolutionTests()
{
_provider = BuildServiceProvider();
}

private static ServiceProvider BuildServiceProvider()
{
IServiceCollection services = new ServiceCollection();
services.AddAutoMapper(typeof(Source).GetTypeInfo().Assembly);
var serviceProvider = services.BuildServiceProvider();
return serviceProvider;
}

[Fact]
public void ShouldResolveConfiguration()
{
_provider.GetService<IConfigurationProvider>().ShouldNotBeNull();
}

[Fact]
public void ShouldConfigureProfiles()
{
_provider.GetService<IConfigurationProvider>().Internal().GetAllTypeMaps().Count.ShouldBe(4);
}

[Fact]
public void ShouldResolveMapper()
{
_provider.GetService<IMapper>().ShouldNotBeNull();
}

[Fact]
public void CanRegisterTwiceWithoutProblems()
{
new Action(() => BuildServiceProvider()).ShouldNotThrow();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;

namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests
{
public class AttributeTests
{
[Fact]
public void Should_not_register_static_instance_when_configured()
{
IServiceCollection services = new ServiceCollection();
services.AddAutoMapper(typeof(Source3));

var serviceProvider = services.BuildServiceProvider();

var mapper = serviceProvider.GetService<IMapper>();

var source = new Source3 {Value = 3};

var dest = mapper.Map<Dest3>(source);

dest.Value.ShouldBe(source.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>AutoMapper.Extensions.Microsoft.DependencyInjection.Tests</AssemblyName>
<PackageId>AutoMapper.Extensions.Microsoft.DependencyInjection.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\AutoMapper\AutoMapper.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" PrivateAssets="All" />
<PackageReference Include="Shouldly" Version="4.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests
{
using System;
using global::Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;

public class DependencyTests
{
private readonly IServiceProvider _provider;

public DependencyTests()
{
IServiceCollection services = new ServiceCollection();
services.AddTransient<ISomeService>(sp => new FooService(5));
services.AddAutoMapper(typeof(Source), typeof(Profile));
_provider = services.BuildServiceProvider();

_provider.GetService<IConfigurationProvider>().AssertConfigurationIsValid();
}

[Fact]
public void ShouldResolveWithDependency()
{
var mapper = _provider.GetService<IMapper>();
var dest = mapper.Map<Source2, Dest2>(new Source2());

dest.ResolvedValue.ShouldBe(5);
}

[Fact]
public void ShouldConvertWithDependency()
{
var mapper = _provider.GetService<IMapper>();
var dest = mapper.Map<Source2, Dest2>(new Source2 { ConvertedValue = 5});

dest.ConvertedValue.ShouldBe(10);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Shouldly;
using Xunit;

namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests.Integrations
{
public class ServiceLifetimeTests
{
internal interface ISingletonService
{
Bar DoTheThing(Foo theObj);
}

internal class TestSingletonService : ISingletonService
{
private readonly IMapper _mapper;

public TestSingletonService(IMapper mapper)
{
_mapper = mapper;
}

public Bar DoTheThing(Foo theObj)
{
var bar = _mapper.Map<Bar>(theObj);
return bar;
}
}

internal class Foo
{
public int TheValue { get; set; }
}

internal class Bar
{
public int TheValue { get; set; }
}


[Fact]
public void CanUseDefaultInjectedIMapperInSingletonService()
{
//arrange
var services = new ServiceCollection();
services.TryAddSingleton<ISingletonService, TestSingletonService>();
services.AddAutoMapper(cfg => cfg.CreateMap<Foo, Bar>().ReverseMap(), GetType().Assembly);
var sp = services.BuildServiceProvider();
Bar actual;

//act
using (var scope = sp.CreateScope())
{
var service = scope.ServiceProvider.GetService<ISingletonService>();
actual = service.DoTheThing(new Foo{TheValue = 1});
}

//assert
actual.ShouldNotBeNull();
actual.TheValue.ShouldBe(1);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;

namespace AutoMapper.Extensions.Microsoft.DependencyInjection.Tests
{
public class MultipleRegistrationTests
{
[Fact]
public void Can_register_multiple_times()
{
var services = new ServiceCollection();

services.AddAutoMapper(cfg => { });
services.AddAutoMapper(cfg => { });
services.AddAutoMapper(cfg => { });

var serviceProvider = services.BuildServiceProvider();

serviceProvider.GetService<IMapper>().ShouldNotBeNull();
}

[Fact]
public void Can_register_assembly_multiple_times()
{
var services = new ServiceCollection();

services.AddAutoMapper(typeof(MultipleRegistrationTests));
services.AddAutoMapper(typeof(MultipleRegistrationTests));
services.AddAutoMapper(typeof(MultipleRegistrationTests));
services.AddTransient<ISomeService, MutableService>();

var serviceProvider = services.BuildServiceProvider();

serviceProvider.GetService<IMapper>().ShouldNotBeNull();
serviceProvider.GetService<DependencyValueConverter>().ShouldNotBeNull();
serviceProvider.GetServices<DependencyValueConverter>().Count().ShouldBe(1);
}
}
}
Loading