You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/Microsoft.AspNet.SignalR.Core/DefaultDependencyResolver.cs

232 lines
8.8 KiB

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.AspNet.SignalR.Configuration;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.AspNet.SignalR.Json;
using Microsoft.AspNet.SignalR.Messaging;
using Microsoft.AspNet.SignalR.Tracing;
using Microsoft.AspNet.SignalR.Transports;
namespace Microsoft.AspNet.SignalR
{
public class DefaultDependencyResolver : IDependencyResolver
{
private readonly Dictionary<Type, IList<Func<object>>> _resolvers = new Dictionary<Type, IList<Func<object>>>();
private readonly HashSet<IDisposable> _trackedDisposables = new HashSet<IDisposable>();
private int _disposed;
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "It's easiest")]
public DefaultDependencyResolver()
{
RegisterDefaultServices();
// Hubs
RegisterHubExtensions();
}
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "The resolver is the class that does the most coupling by design.")]
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The resolver disposes dependencies on Dispose.")]
private void RegisterDefaultServices()
{
var traceManager = new Lazy<TraceManager>(() => new TraceManager());
Register(typeof(ITraceManager), () => traceManager.Value);
var serverIdManager = new ServerIdManager();
Register(typeof(IServerIdManager), () => serverIdManager);
var serverMessageHandler = new Lazy<IServerCommandHandler>(() => new ServerCommandHandler(this));
Register(typeof(IServerCommandHandler), () => serverMessageHandler.Value);
var newMessageBus = new Lazy<IMessageBus>(() => new MessageBus(this));
Register(typeof(IMessageBus), () => newMessageBus.Value);
var stringMinifier = new Lazy<IStringMinifier>(() => new StringMinifier());
Register(typeof(IStringMinifier), () => stringMinifier.Value);
var serializer = new Lazy<JsonNetSerializer>();
Register(typeof(IJsonSerializer), () => serializer.Value);
var transportManager = new Lazy<TransportManager>(() => new TransportManager(this));
Register(typeof(ITransportManager), () => transportManager.Value);
var configurationManager = new DefaultConfigurationManager();
Register(typeof(IConfigurationManager), () => configurationManager);
var transportHeartbeat = new Lazy<TransportHeartbeat>(() => new TransportHeartbeat(this));
Register(typeof(ITransportHeartbeat), () => transportHeartbeat.Value);
var connectionManager = new Lazy<ConnectionManager>(() => new ConnectionManager(this));
Register(typeof(IConnectionManager), () => connectionManager.Value);
var ackHandler = new Lazy<AckHandler>();
Register(typeof(IAckHandler), () => ackHandler.Value);
var perfCounterWriter = new Lazy<PerformanceCounterManager>(() => new PerformanceCounterManager(this));
Register(typeof(IPerformanceCounterManager), () => perfCounterWriter.Value);
var protectedData = new DefaultProtectedData();
Register(typeof(IProtectedData), () => protectedData);
}
private void RegisterHubExtensions()
{
var methodDescriptorProvider = new Lazy<ReflectedMethodDescriptorProvider>();
Register(typeof(IMethodDescriptorProvider), () => methodDescriptorProvider.Value);
var hubDescriptorProvider = new Lazy<ReflectedHubDescriptorProvider>(() => new ReflectedHubDescriptorProvider(this));
Register(typeof(IHubDescriptorProvider), () => hubDescriptorProvider.Value);
var parameterBinder = new Lazy<DefaultParameterResolver>();
Register(typeof(IParameterResolver), () => parameterBinder.Value);
var activator = new Lazy<DefaultHubActivator>(() => new DefaultHubActivator(this));
Register(typeof(IHubActivator), () => activator.Value);
var hubManager = new Lazy<DefaultHubManager>(() => new DefaultHubManager(this));
Register(typeof(IHubManager), () => hubManager.Value);
var proxyGenerator = new Lazy<DefaultJavaScriptProxyGenerator>(() => new DefaultJavaScriptProxyGenerator(this));
Register(typeof(IJavaScriptProxyGenerator), () => proxyGenerator.Value);
var requestParser = new Lazy<HubRequestParser>();
Register(typeof(IHubRequestParser), () => requestParser.Value);
var assemblyLocator = new Lazy<DefaultAssemblyLocator>(() => new DefaultAssemblyLocator());
Register(typeof(IAssemblyLocator), () => assemblyLocator.Value);
// Setup the default hub pipeline
var dispatcher = new Lazy<IHubPipeline>(() => new HubPipeline().AddModule(new AuthorizeModule()));
Register(typeof(IHubPipeline), () => dispatcher.Value);
Register(typeof(IHubPipelineInvoker), () => dispatcher.Value);
}
public virtual object GetService(Type serviceType)
{
if (serviceType == null)
{
throw new ArgumentNullException("serviceType");
}
IList<Func<object>> activators;
if (_resolvers.TryGetValue(serviceType, out activators))
{
if (activators.Count == 0)
{
return null;
}
if (activators.Count > 1)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.Error_MultipleActivatorsAreaRegisteredCallGetServices, serviceType.FullName));
}
return Track(activators[0]);
}
return null;
}
public virtual IEnumerable<object> GetServices(Type serviceType)
{
IList<Func<object>> activators;
if (_resolvers.TryGetValue(serviceType, out activators))
{
if (activators.Count == 0)
{
return null;
}
return activators.Select(Track).ToList();
}
return null;
}
public virtual void Register(Type serviceType, Func<object> activator)
{
IList<Func<object>> activators;
if (!_resolvers.TryGetValue(serviceType, out activators))
{
activators = new List<Func<object>>();
_resolvers.Add(serviceType, activators);
}
else
{
activators.Clear();
}
activators.Add(activator);
}
public virtual void Register(Type serviceType, IEnumerable<Func<object>> activators)
{
if (activators == null)
{
throw new ArgumentNullException("activators");
}
IList<Func<object>> list;
if (!_resolvers.TryGetValue(serviceType, out list))
{
list = new List<Func<object>>();
_resolvers.Add(serviceType, list);
}
else
{
list.Clear();
}
foreach (var a in activators)
{
list.Add(a);
}
}
private object Track(Func<object> creator)
{
object obj = creator();
if (_disposed == 0)
{
var disposable = obj as IDisposable;
if (disposable != null)
{
lock (_trackedDisposables)
{
if (_disposed == 0)
{
_trackedDisposables.Add(disposable);
}
}
}
}
return obj;
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Interlocked.Exchange(ref _disposed, 1) == 0)
{
lock (_trackedDisposables)
{
foreach (var d in _trackedDisposables)
{
d.Dispose();
}
_trackedDisposables.Clear();
}
}
}
}
public void Dispose()
{
Dispose(true);
}
}
}