Browse Source

Part 1 of a multi-PR change for Emby.DLNA

BaronGreenback 5 years ago
parent
commit
ab10f21027

+ 39 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -351,6 +351,42 @@ namespace Emby.Server.Implementations
         public object CreateInstance(Type type)
         public object CreateInstance(Type type)
             => ActivatorUtilities.CreateInstance(ServiceProvider, type);
             => ActivatorUtilities.CreateInstance(ServiceProvider, type);
 
 
+        /// <summary>
+        /// Creates an instance of type and resolves all constructor dependencies.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <param name="parameter">Additional argument for the constructor.</param>
+        /// <returns></returns>
+        public object CreateInstance(Type type, object parameter)
+        {
+            ConstructorInfo constructor = type.GetConstructors()[0];
+            if (constructor != null)
+            {
+                ParameterInfo[] argInfo = constructor
+                    .GetParameters();
+
+                object[] args = argInfo
+                .Select(o => o.ParameterType)
+                .Select(o => ServiceProvider.GetService(o))
+                .ToArray();
+
+                if (parameter != null)
+                {
+                    // Assumption is that the <parameter> is always the last in the constructor's parameter list.
+                    int argsLen = args.Length;
+                    var argType = argInfo[argsLen - 1].ParameterType;
+                    var paramType = parameter.GetType();
+                    if (argType.IsAssignableFrom(paramType) || argType == paramType)
+                    {
+                        args[argsLen - 1] = parameter;
+                        return ActivatorUtilities.CreateInstance(ServiceProvider, type, args);
+                    }
+                }
+            }
+
+            return ActivatorUtilities.CreateInstance(ServiceProvider, type);
+        }
+
         /// <summary>
         /// <summary>
         /// Creates an instance of type and resolves all constructor dependencies.
         /// Creates an instance of type and resolves all constructor dependencies.
         /// </summary>
         /// </summary>
@@ -566,8 +602,10 @@ namespace Emby.Server.Implementations
             serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
             serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
 
 
             // TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
             // TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
+            // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation
             serviceCollection.AddTransient(provider => new Lazy<EncodingHelper>(provider.GetRequiredService<EncodingHelper>));
             serviceCollection.AddTransient(provider => new Lazy<EncodingHelper>(provider.GetRequiredService<EncodingHelper>));
-            serviceCollection.AddSingleton<IMediaEncoder, MediaBrowser.MediaEncoding.Encoder.MediaEncoder>();
+            serviceCollection.AddSingleton<IMediaEncoder>(provider =>
+                ActivatorUtilities.CreateInstance<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(provider, _startupOptions.FFmpegPath ?? string.Empty));
 
 
             // TODO: Refactor to eliminate the circular dependencies here so that Lazy<T> isn't required
             // TODO: Refactor to eliminate the circular dependencies here so that Lazy<T> isn't required
             serviceCollection.AddTransient(provider => new Lazy<ILibraryMonitor>(provider.GetRequiredService<ILibraryMonitor>));
             serviceCollection.AddTransient(provider => new Lazy<ILibraryMonitor>(provider.GetRequiredService<ILibraryMonitor>));

+ 5 - 0
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -107,6 +107,11 @@ namespace Emby.Server.Implementations.HttpServer
             return _appHost.CreateInstance(type);
             return _appHost.CreateInstance(type);
         }
         }
 
 
+        public object CreateInstance(Type type, object parameter)
+        {
+            return _appHost.CreateInstance(type, parameter);
+        }
+
         private static string NormalizeUrlPath(string path)
         private static string NormalizeUrlPath(string path)
         {
         {
             if (path.Length > 0 && path[0] == '/')
             if (path.Length > 0 && path[0] == '/')

+ 2 - 2
Emby.Server.Implementations/Services/ServiceController.cs

@@ -177,8 +177,8 @@ namespace Emby.Server.Implementations.Services
 
 
             var serviceType = httpHost.GetServiceTypeByRequest(requestType);
             var serviceType = httpHost.GetServiceTypeByRequest(requestType);
 
 
-            var service = httpHost.CreateInstance(serviceType);
-
+            var service = httpHost.CreateInstance(serviceType, req);
+            
             var serviceRequiresContext = service as IRequiresRequest;
             var serviceRequiresContext = service as IRequiresRequest;
             if (serviceRequiresContext != null)
             if (serviceRequiresContext != null)
             {
             {

+ 8 - 0
MediaBrowser.Common/IApplicationHost.cs

@@ -125,5 +125,13 @@ namespace MediaBrowser.Common
         /// <param name="type">The type.</param>
         /// <param name="type">The type.</param>
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         object CreateInstance(Type type);
         object CreateInstance(Type type);
+
+        /// <summary>
+        /// Creates a new instance of a class.
+        /// </summary>
+        /// <param name="type">The type to create.</param>
+        /// <param name="parameter">An addtional parameter.</param>
+        /// <returns>Created instance.</returns>
+        object CreateInstance(Type type, object parameter);
     }
     }
 }
 }