Add bootstrapper for Microsoft.Extensions.DependencyInjection

This commit is contained in:
Antony Male 2021-02-13 23:13:02 +00:00
parent 520fe7416d
commit 53393a35eb
6 changed files with 178 additions and 2 deletions

View File

@ -9,8 +9,9 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Bootstrappers</RootNamespace>
<AssemblyName>Bootstrappers</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -41,6 +42,15 @@
<Reference Include="Castle.Windsor">
<HintPath>packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=5.0.0.1, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Extensions.DependencyInjection.5.0.1\lib\net461\Microsoft.Extensions.DependencyInjection.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Practices.Unity">
<HintPath>packages\Unity.3.5.1404.0\lib\net45\Microsoft.Practices.Unity.dll</HintPath>
</Reference>
@ -68,6 +78,12 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -80,12 +96,14 @@
<Compile Include="NinjectBootstrapper.cs" />
<Compile Include="NoIoCContainerBootstrapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="MicrosoftDependencyInjectionBootstrapper.cs" />
<Compile Include="StructureMapBootstrapper.cs" />
<Compile Include="Tests\AutofacTests.cs" />
<Compile Include="Tests\BootstrapperTests.cs" />
<Compile Include="Tests\CastleWindsorTests.cs" />
<Compile Include="Tests\NinjectTests.cs" />
<Compile Include="Tests\NoIoCContainerTests.cs" />
<Compile Include="Tests\MicrosoftDependencyInjectionTests.cs" />
<Compile Include="Tests\StructureMapTests.cs" />
<Compile Include="Tests\StubType.cs" />
<Compile Include="Tests\UnityTests.cs" />

View File

@ -39,7 +39,7 @@ namespace Bootstrappers
};
// Stylet does its own disposal of ViewModels: Castle Windsor shouldn't be doing the same
// Castle Windsor seems to be ver opinionated on this point, insisting that the container
// Castle Windsor seems to be very opinionated on this point, insisting that the container
// should be responsible for disposing all components. This is at odds with Stylet's approach
// (and indeed common sense).
#pragma warning disable CS0618 // Type or member is obsolete

View File

@ -0,0 +1,79 @@
using Autofac;
using Microsoft.Extensions.DependencyInjection;
using Stylet;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Bootstrappers
{
public class MicrosoftDependencyInjectionBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private ServiceProvider serviceProvider;
private object _rootViewModel;
protected virtual object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
public IServiceProvider ServiceProvider
{
get { return this.serviceProvider; }
}
protected override void ConfigureBootstrapper()
{
var services = new ServiceCollection();
this.DefaultConfigureIoC(services);
this.ConfigureIoC(services);
this.serviceProvider = services.BuildServiceProvider();
}
/// <summary>
/// Carries out default configuration of the IoC container. Override if you don't want to do this
/// </summary>
protected virtual void DefaultConfigureIoC(IServiceCollection services)
{
var viewManagerConfig = new ViewManagerConfig()
{
ViewFactory = this.GetInstance,
ViewAssemblies = new List<Assembly>() { this.GetType().Assembly }
};
services.AddSingleton<IViewManager>(new ViewManager(viewManagerConfig));
services.AddTransient<MessageBoxView>();
services.AddSingleton<IWindowManagerConfig>(this);
services.AddSingleton<IWindowManager, WindowManager>();
services.AddSingleton<IEventAggregator, EventAggregator>();
services.AddTransient<IMessageBoxViewModel, MessageBoxViewModel>(); // Not singleton!
// Also need a factory
services.AddSingleton<Func<IMessageBoxViewModel>>(() => new MessageBoxViewModel());
}
/// <summary>
/// Override to add your own types to the IoC container.
/// </summary>
protected virtual void ConfigureIoC(IServiceCollection services) { }
public override object GetInstance(Type type)
{
return this.serviceProvider.GetRequiredService(type);
}
protected override void Launch()
{
base.DisplayRootView(this.RootViewModel);
}
public override void Dispose()
{
base.Dispose();
ScreenExtensions.TryDispose(this._rootViewModel);
if (this.serviceProvider != null)
this.serviceProvider.Dispose();
}
}
}

View File

@ -159,6 +159,9 @@ namespace Bootstrappers.Tests
[Test]
public void DoesNotDisposeTransientInstances()
{
if (!this.Autobinds)
Assert.Ignore("Autobinding not supported");
StubType.Reset();
var vm = this.bootstrapper.GetInstance(typeof(StubType));

View File

@ -0,0 +1,71 @@
using Autofac;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bootstrappers.Tests
{
public class MyMicrosoftDependencyInjectionBootstrapper : MicrosoftDependencyInjectionBootstrapper<TestRootViewModel>, ITestBootstrapper
{
public List<string> ConfigureLog { get; set; }
public int DisposeCount { get; private set; }
public MyMicrosoftDependencyInjectionBootstrapper()
{
this.ConfigureLog = new List<string>();
}
protected override void Configure()
{
base.Configure();
this.ConfigureLog.Add("Configure");
}
protected override void DefaultConfigureIoC(IServiceCollection services)
{
base.DefaultConfigureIoC(services);
this.ConfigureLog.Add("DefaultConfigureIoC");
}
protected override void ConfigureIoC(IServiceCollection services)
{
base.ConfigureIoC(services);
this.ConfigureLog.Add("ConfigureIoC");
}
public new object GetInstance(Type type)
{
return base.GetInstance(type);
}
public new void ConfigureBootstrapper()
{
base.ConfigureBootstrapper();
}
public override void Dispose()
{
base.Dispose();
this.DisposeCount++;
}
}
[TestFixture(Category = "ServiceCollection")]
public class MicrosoftDependencyInjectionTests : BootstrapperTests<MyMicrosoftDependencyInjectionBootstrapper>
{
public MicrosoftDependencyInjectionTests()
{
this.Autobinds = false;
}
public override MyMicrosoftDependencyInjectionBootstrapper CreateBootstrapper()
{
return new MyMicrosoftDependencyInjectionBootstrapper();
}
}
}

View File

@ -3,9 +3,14 @@
<package id="Autofac" version="4.2.1" targetFramework="net45" />
<package id="Castle.Core" version="3.3.3" targetFramework="net45" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net45" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="5.0.0" targetFramework="net472" />
<package id="Microsoft.Extensions.DependencyInjection" version="5.0.1" targetFramework="net472" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="5.0.0" targetFramework="net472" />
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="NUnit" version="3.5.0" targetFramework="net45" />
<package id="NUnit3TestAdapter" version="3.6.0" targetFramework="net45" />
<package id="structuremap" version="3.1.6.186" targetFramework="net45" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
<package id="Unity" version="3.5.1404.0" targetFramework="net45" />
</packages>