Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weitzhandler/adeeb13b64544d4e9fc286958a50ccfb to your computer and use it in GitHub Desktop.
Save weitzhandler/adeeb13b64544d4e9fc286958a50ccfb to your computer and use it in GitHub Desktop.
// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using ReactiveUI;
namespace Splat.Microsoft
{
public static class MicrosoftDependencyResolverExtensions
{
public static void UseMicrosoftDependencyResolver(this IServiceCollection services)
{
var resolver = new MicrosoftDependencyResolver(services);
Locator.SetLocator(resolver);
services.AddSingleton<IMicrosoftDependencyResolver>(resolver);
resolver.InitializeReactiveUI();
}
}
interface IMicrosoftDependencyResolver : IDependencyResolver
{
/// <summary>
/// Uses to inject the service provider once it't ready.
/// </summary>
/// <param name="container"></param>
void UpdateContainer(IServiceProvider container);
}
public class MicrosoftDependencyResolver : IMicrosoftDependencyResolver
{
bool locked;
readonly IServiceCollection _Services;
IServiceProvider _Container;
IServiceProvider Container
{
get
{
if (_Container == null)
_Container = _Services.BuildServiceProvider();
return _Container;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="MicrosoftDependencyResolver" /> class.
/// </summary>
/// <param name="services">The container.</param>
public MicrosoftDependencyResolver(IServiceCollection services)
{
_Services = services;
}
/// </inheritdoc>
public void UpdateContainer(IServiceProvider container)
{
_Container = container;
locked = true;
}
/// <inheritdoc />
public virtual object GetService(Type serviceType, string contract = null) =>
Container.GetRequiredService(serviceType);
/// <inheritdoc />
public virtual IEnumerable<object> GetServices(Type serviceType, string contract = null) =>
Container.GetServices(serviceType);
/// <inheritdoc />
public virtual void Register(Func<object> factory, Type serviceType, string contract = null)
{
if (locked)
throw new InvalidOperationException("Service provider has already been initialized.");
_Services.AddSingleton(serviceType, (provider) => factory());
}
/// <inheritdoc />
public virtual void UnregisterCurrent(Type serviceType, string contract = null)
{
if (locked)
throw new InvalidOperationException("Service provider has already been initialized.");
UnregisterAll(serviceType);
}
/// <inheritdoc />
public virtual void UnregisterAll(Type serviceType, string contract = null)
{
if (locked)
throw new InvalidOperationException("Service provider has already been initialized.");
var remove = _Services.Where(sd => sd.ServiceType == serviceType).ToArray();
foreach (var item in remove)
_Services.Remove(item);
}
/// <inheritdoc />
public virtual IDisposable ServiceRegistrationCallback(Type serviceType, string contract, Action<IDisposable> callback)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes of the instance.
/// </summary>
/// <param name="disposing">Whether or not the instance is disposing.</param>
protected virtual void Dispose(bool disposing)
{
if (disposing && !locked)
_Services.Clear();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment