Skip to content
Browse files

Refactored auto wire container functionality

  • Loading branch information...
1 parent dab55b2 commit ac18dd379fd80060dd5c2278992f6585c59894fe @Arxisos Arxisos committed Jan 30, 2012
View
8 src/ServiceStack.FluentValidation.Mvc3/Mvc/FunqControllerFactory.cs
@@ -12,21 +12,19 @@ namespace ServiceStack.Mvc
{
public class FunqControllerFactory : DefaultControllerFactory
{
- private readonly AutoWireContainer funqBuilder;
+ private readonly ContainerResolveCache funqBuilder;
public FunqControllerFactory(Container container)
{
- this.funqBuilder = new AutoWireContainer(container) {
- Scope = ReuseScope.None //don't re-use instances
- };
+ this.funqBuilder = new ContainerResolveCache(container);
// Also register all the controller types as transient
var controllerTypes =
(from type in Assembly.GetCallingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(type)
select type).ToList();
- funqBuilder.RegisterTypes(controllerTypes);
+ container.RegisterAutoWiredTypes(controllerTypes);
}
protected override IController GetControllerInstance(
View
6 src/ServiceStack.FluentValidation.Mvc3/Mvc/FunqValidatorBase.cs
@@ -8,13 +8,11 @@ namespace ServiceStack.Mvc
{
public class FunqValidatorFactory : ValidatorFactoryBase
{
- private readonly AutoWireContainer funqBuilder;
+ private readonly ContainerResolveCache funqBuilder;
public FunqValidatorFactory(Container container=null)
{
- this.funqBuilder = new AutoWireContainer(container ?? AppHostBase.Instance.Container) {
- Scope = ReuseScope.None //don't re-use instances
- };
+ this.funqBuilder = new ContainerResolveCache(container ?? AppHostBase.Instance.Container);
}
public override IValidator CreateInstance(Type validatorType)
View
3 src/ServiceStack.ServiceInterface/Testing/BasicAppHost.cs
@@ -20,8 +20,7 @@ public BasicAppHost()
public void RegisterAs<T, TAs>() where T : TAs
{
- var autoWire = new AutoWireContainer(this.Container);
- autoWire.RegisterAs<T, TAs>();
+ this.Container.RegisterAs<T, TAs>();
}
public virtual void Release(object instance) { }
View
3 src/ServiceStack.ServiceInterface/Testing/TestAppHost.cs
@@ -36,8 +36,7 @@ public TestAppHost(Funq.Container container, params Assembly[] serviceAssemblies
public void RegisterAs<T, TAs>() where T : TAs
{
- var autoWire = new AutoWireContainer(container);
- autoWire.RegisterAs<T, TAs>();
+ this.container.RegisterAs<T, TAs>();
}
public virtual void Release(object instance) { }
View
12 src/ServiceStack.ServiceInterface/Validation/ValidationFeature.cs
@@ -34,34 +34,28 @@ public static void Init(IAppHost appHost)
/// <param name="assemblies">The assemblies to scan for a validator</param>
public static void RegisterValidators(this Container container, params Assembly[] assemblies)
{
- var autoWire = new AutoWireContainer(container);
foreach (var assembly in assemblies)
{
foreach (var validator in assembly.GetTypes()
.Where(t => t.IsOrHasGenericInterfaceTypeOf(typeof(IValidator<>))))
{
- RegisterValidator(autoWire, validator);
+ RegisterValidator(container, validator);
}
}
}
public static void RegisterValidator(this Container container, Type validator)
{
- RegisterValidator(new AutoWireContainer(container), validator);
- }
-
- private static void RegisterValidator(AutoWireContainer autoWire, Type validator)
- {
var baseType = validator.BaseType;
while (!baseType.IsGenericType)
{
baseType = baseType.BaseType;
}
var dtoType = baseType.GetGenericArguments()[0];
- var validatorType = typeof (IValidator<>).MakeGenericType(dtoType);
+ var validatorType = typeof(IValidator<>).MakeGenericType(dtoType);
- autoWire.RegisterType(validator, validatorType);
+ container.RegisterAutoWiredType(validator, validatorType);
}
}
}
View
145 src/ServiceStack/Funq/AutoWireHelpers.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using Funq;
+using ServiceStack.Configuration;
+using ServiceStack.Text;
+using ServiceStack.CacheAccess;
+using System.Threading;
+using System.Collections;
+
+namespace Funq
+{
+ public static class AutoWireHelpers
+ {
+ private static Dictionary<Type, Action<object>[]> autoWireCache = new Dictionary<Type, Action<object>[]>();
+
+ private static MethodInfo GetResolveMethod(Type typeWithResolveMethod, Type serviceType)
+ {
+ var methodInfo = typeWithResolveMethod.GetMethod("Resolve", new Type[0]);
+ return methodInfo.MakeGenericMethod(new[] { serviceType });
+ }
+
+ public static ConstructorInfo GetConstructorWithMostParams(Type type)
+ {
+ return type.GetConstructors()
+ .OrderByDescending(x => x.GetParameters().Length)
+ .First(ctor => !ctor.IsStatic);
+ }
+
+ /// <summary>
+ /// Generates a function which creates and auto-wires <see cref="TService"/>.
+ /// </summary>
+ /// <typeparam name="TService"></typeparam>
+ /// <param name="lambdaParam"></param>
+ /// <returns></returns>
+ public static Func<Container, TService> GenerateAutoWireFn<TService>()
+ {
+ var lambdaParam = Expression.Parameter(typeof(Container), "container");
+ var propertyResolveFn = typeof(Container).GetMethod("TryResolve", new Type[0]);
+ var memberBindings = typeof(TService).GetPublicProperties()
+ .Where(x => x.CanWrite && !x.PropertyType.IsValueType)
+ .Select(x =>
+ Expression.Bind
+ (
+ x,
+ ResolveTypeExpression(propertyResolveFn, x.PropertyType, lambdaParam)
+ )
+ ).ToArray();
+
+ var ctorResolveFn = typeof(Container).GetMethod("Resolve", new Type[0]);
+ return Expression.Lambda<Func<Container, TService>>
+ (
+ Expression.MemberInit
+ (
+ ConstrcutorExpression(ctorResolveFn, typeof(TService), lambdaParam),
+ memberBindings
+ ),
+ lambdaParam
+ ).Compile();
+ }
+
+ /// <summary>
+ /// Auto-wires an existing instance of a specific type.
+ /// The auto-wiring progress is also cached to be faster
+ /// when calling next time with the same type.
+ /// </summary>
+ /// <param name="instance"></param>
+ public static void AutoWire(Container container, object instance)
+ {
+ var instanceType = instance.GetType();
+ var propertyResolveFn = typeof(Container).GetMethod("TryResolve", new Type[0]);
+
+ Action<object>[] setters;
+ if (!autoWireCache.TryGetValue(instanceType, out setters))
+ {
+ setters = instanceType.GetPublicProperties()
+ .Where(x => x.CanWrite && !x.PropertyType.IsValueType)
+ .Select(x => GenerateAutoWireFnForProperty(container, propertyResolveFn, x, instanceType))
+ .ToArray();
+
+ //Support for multiple threads is needed
+ Dictionary<Type, Action<object>[]> snapshot, newCache;
+ do
+ {
+ snapshot = autoWireCache;
+ newCache = new Dictionary<Type, Action<object>[]>(autoWireCache);
+ newCache[instanceType] = setters;
+ } while (!ReferenceEquals(
+ Interlocked.CompareExchange(ref autoWireCache, newCache, snapshot), snapshot));
+ }
+
+ foreach (var setter in setters)
+ setter(instance);
+ }
+
+ private static Action<object> GenerateAutoWireFnForProperty(
+ Container container, MethodInfo propertyResolveFn, PropertyInfo property, Type instanceType)
+ {
+ var instanceParam = Expression.Parameter(typeof(object), "instance");
+ var containerParam = Expression.Constant(container);
+
+ Func<object, object> getter = Expression.Lambda<Func<object, object>>(
+ Expression.Call(
+ Expression.Convert(instanceParam, instanceType),
+ property.GetGetMethod()
+ ),
+ instanceParam
+ ).Compile();
+
+ Action<object> setter = Expression.Lambda<Action<object>>(
+ Expression.Call(
+ Expression.Convert(instanceParam, instanceType),
+ property.GetSetMethod(),
+ ResolveTypeExpression(propertyResolveFn, property.PropertyType, containerParam)
+ ),
+ instanceParam
+ ).Compile();
+
+ return obj => {
+ if (getter(obj) == null) setter(obj);
+ };
+ }
+
+ private static NewExpression ConstrcutorExpression(
+ MethodInfo resolveMethodInfo, Type type, Expression lambdaParam)
+ {
+ var ctorWithMostParameters = GetConstructorWithMostParams(type);
+
+ var constructorParameterInfos = ctorWithMostParameters.GetParameters();
+ var regParams = constructorParameterInfos
+ .Select(pi => ResolveTypeExpression(resolveMethodInfo, pi.ParameterType, lambdaParam));
+
+ return Expression.New(ctorWithMostParameters, regParams.ToArray());
+ }
+
+ private static MethodCallExpression ResolveTypeExpression(
+ MethodInfo resolveFn, Type resolveType, Expression containerParam)
+ {
+ var method = resolveFn.MakeGenericMethod(resolveType);
+ return Expression.Call(containerParam, method);
+ }
+ }
+}
View
41 src/ServiceStack/Funq/Container.Adapter.cs
@@ -8,24 +8,13 @@ public partial class Container
{
public IContainerAdapter Adapter { get; set; }
- private AutoWireContainer autoWireContainer;
- internal AutoWireContainer AutoWireContainer
- {
- get
- {
- if (autoWireContainer == null)
- autoWireContainer = new AutoWireContainer(this);
- return autoWireContainer;
- }
- }
-
/// <summary>
/// Register an autowired dependency
/// </summary>
/// <typeparam name="T"></typeparam>
public IRegistration<T> RegisterAutoWired<T>()
{
- var serviceFactory = AutoWireContainer.GenerateAutoWireFn<T>();
+ var serviceFactory = AutoWireHelpers.GenerateAutoWireFn<T>();
return this.Register(serviceFactory);
}
@@ -36,7 +25,7 @@ public IRegistration<T> RegisterAutoWired<T>()
public IRegistration<TAs> RegisterAutoWiredAs<T, TAs>()
where T : TAs
{
- var serviceFactory = AutoWireContainer.GenerateAutoWireFn<T>();
+ var serviceFactory = AutoWireHelpers.GenerateAutoWireFn<T>();
Func<Container, TAs> fn = c => serviceFactory(c);
return this.Register(fn);
}
@@ -58,32 +47,8 @@ public IRegistration<T> RegisterAutoWired<T>()
/// <param name="instance"></param>
public void AutoWire(object instance)
{
- AutoWireContainer.AutoWire(instance);
- }
-
- /// <summary>
- /// Registers the types in the IoC container and
- /// adds auto-wiring to the specified types.
- /// Additionaly the creation of the types is cached when calling <see cref="CreateInstance"/> on the same instance.
- /// </summary>
- /// <param name="serviceTypes"></param>
- public void RegisterTypes(params Type[] serviceTypes)
- {
- AutoWireContainer.RegisterTypes(serviceTypes);
+ AutoWireHelpers.AutoWire(this, instance);
}
-
- /// <summary>
- /// Registers the type in the IoC container and
- /// adds auto-wiring to the specified type.
- /// Additionaly the creation of the type is cached when calling <see cref="CreateInstance"/> on the same instance.
- /// </summary>
- /// <param name="serviceType"></param>
- /// <param name="inFunqAsType"></param>
- public void RegisterType(Type serviceType, Type inFunqAsType)
- {
- AutoWireContainer.RegisterType(serviceType, inFunqAsType);
- }
-
}
}
View
274 src/ServiceStack/ServiceHost/AutoWireContainer.cs
@@ -1,274 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using Funq;
-using ServiceStack.Configuration;
-using ServiceStack.Text;
-using ServiceStack.CacheAccess;
-using System.Threading;
-using System.Collections;
-
-namespace ServiceStack.ServiceHost
-{
- public class AutoWireContainer
- : ITypeFactory
- {
- protected Container container;
-
- private readonly Dictionary<Type, Func<object>> resolveFnMap = new Dictionary<Type, Func<object>>();
- private Dictionary<Type, Action<object>[]> autoWireCache = new Dictionary<Type, Action<object>[]>();
-
- /// <summary>
- /// Determines in which scope the types registered will be saved in the Funq container.
- /// </summary>
- public ReuseScope Scope { get; set; }
-
- public AutoWireContainer(Container container)
- {
- this.container = container;
- this.Scope = ReuseScope.None;
- }
-
- protected static MethodInfo GetResolveMethod(Type typeWithResolveMethod, Type serviceType)
- {
- var methodInfo = typeWithResolveMethod.GetMethod("Resolve", new Type[0]);
- return methodInfo.MakeGenericMethod(new[] { serviceType });
- }
-
- public static ConstructorInfo GetConstructorWithMostParams(Type type)
- {
- return type.GetConstructors()
- .OrderByDescending(x => x.GetParameters().Length)
- .First(ctor => !ctor.IsStatic);
- }
-
- /// <summary>
- /// Generates a function which creates and auto-wires <see cref="TService"/>.
- /// </summary>
- /// <typeparam name="TService"></typeparam>
- /// <param name="lambdaParam"></param>
- /// <returns></returns>
- public Func<Container, TService> GenerateAutoWireFn<TService>()
- {
- var lambdaParam = Expression.Parameter(typeof(Container), "container");
- var propertyResolveFn = typeof(Container).GetMethod("TryResolve", new Type[0]);
- var memberBindings = typeof(TService).GetPublicProperties()
- .Where(x => x.CanWrite && !x.PropertyType.IsValueType)
- .Select(x =>
- Expression.Bind
- (
- x,
- ResolveTypeExpression(propertyResolveFn, x.PropertyType, lambdaParam)
- )
- ).ToArray();
-
- var ctorResolveFn = typeof(Container).GetMethod("Resolve", new Type[0]);
- return Expression.Lambda<Func<Container, TService>>
- (
- Expression.MemberInit
- (
- ConstrcutorExpression(ctorResolveFn, typeof(TService), lambdaParam),
- memberBindings
- ),
- lambdaParam
- ).Compile();
- }
-
- /// <summary>
- /// Auto-wires an existing instance of a specific type.
- /// The auto-wiring progress is also cached to be faster
- /// when calling next time with the same type.
- /// </summary>
- /// <param name="instance"></param>
- public void AutoWire(object instance)
- {
- var instanceType = instance.GetType();
- var propertyResolveFn = typeof(Container).GetMethod("TryResolve", new Type[0]);
-
- Action<object>[] setters;
- if (!this.autoWireCache.TryGetValue(instanceType, out setters))
- {
- setters = instanceType.GetPublicProperties()
- .Where(x => x.CanWrite && !x.PropertyType.IsValueType)
- .Select(x => this.GenerateAutoWireFnForProperty(propertyResolveFn, x, instanceType))
- .ToArray();
-
- //Support for multiple threads is needed
- Dictionary<Type, Action<object>[]> snapshot, newCache;
- do
- {
- snapshot = autoWireCache;
- newCache = new Dictionary<Type, Action<object>[]>(autoWireCache);
- newCache[instanceType] = setters;
- } while (!ReferenceEquals(
- Interlocked.CompareExchange(ref autoWireCache, newCache, snapshot), snapshot));
- }
-
- foreach (var setter in setters)
- setter(instance);
- }
-
- private Action<object> GenerateAutoWireFnForProperty(
- MethodInfo propertyResolveFn, PropertyInfo property, Type instanceType)
- {
- var instanceParam = Expression.Parameter(typeof(object), "instance");
- var containerParam = Expression.Constant(this.container);
-
- Func<object, object> getter = Expression.Lambda<Func<object, object>>(
- Expression.Call(
- Expression.Convert(instanceParam, instanceType),
- property.GetGetMethod()
- ),
- instanceParam
- ).Compile();
-
- Action<object> setter = Expression.Lambda<Action<object>>(
- Expression.Call(
- Expression.Convert(instanceParam, instanceType),
- property.GetSetMethod(),
- ResolveTypeExpression(propertyResolveFn, property.PropertyType, containerParam)
- ),
- instanceParam
- ).Compile();
-
- return obj => {
- if (getter(obj) == null) setter(obj);
- };
- }
-
- private static NewExpression ConstrcutorExpression(
- MethodInfo resolveMethodInfo, Type type, Expression lambdaParam)
- {
- var ctorWithMostParameters = GetConstructorWithMostParams(type);
-
- var constructorParameterInfos = ctorWithMostParameters.GetParameters();
- var regParams = constructorParameterInfos
- .Select(pi => ResolveTypeExpression(resolveMethodInfo, pi.ParameterType, lambdaParam));
-
- return Expression.New(ctorWithMostParameters, regParams.ToArray());
- }
-
- private static MethodCallExpression ResolveTypeExpression(
- MethodInfo resolveFn, Type resolveType, Expression containerParam)
- {
- var method = resolveFn.MakeGenericMethod(resolveType);
- return Expression.Call(containerParam, method);
- }
-
- /// <summary>
- /// Registers the type in the IoC container passed in the constructor and
- /// adds auto-wiring to the specified type.
- /// Auto-wiring is not cached with this method!
- /// The type is registered in transient scope.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void Register<T>()
- {
- var serviceFactory = GenerateAutoWireFn<T>();
- container.Register(serviceFactory).ReusedWithin(this.Scope);
-
- this.resolveFnMap[typeof(T)] = () => serviceFactory(this.container);
- }
-
- /// <summary>
- /// Registers the type in the IoC container passed in the constructor and
- /// adds auto-wiring to the specified type.
- /// Auto-wiring is not cached with this method!
- /// The type is registered in transient scope.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <typeparam name="TAs"></typeparam>
- public void RegisterAs<T, TAs>()
- where T : TAs
- {
- var serviceFactory = GenerateAutoWireFn<T>();
-
- Func<Container, TAs> fn = c => serviceFactory(c);
-
- this.container.Register(fn).ReusedWithin(this.Scope);
-
- this.resolveFnMap[typeof(TAs)] = () => fn(this.container);
- }
-
- /// <summary>
- /// Registers the type in the IoC container and
- /// adds auto-wiring to the specified type.
- /// Additionaly the creation of the type is cached when calling <see cref="CreateInstance"/> on the same instance.
- /// </summary>
- /// <param name="serviceType"></param>
- /// <param name="inFunqAsType"></param>
- public void RegisterType(Type serviceType, Type inFunqAsType)
- {
- if (serviceType.IsAbstract || serviceType.ContainsGenericParameters)
- return;
-
- var methodInfo = GetType().GetMethod("RegisterAs", Type.EmptyTypes);
- var registerMethodInfo = methodInfo.MakeGenericMethod(new[] { serviceType, inFunqAsType });
- registerMethodInfo.Invoke(this, new object[0]);
-
- GenerateServiceFactory(serviceType);
- }
-
- /// <summary>
- /// Registers the types in the IoC container and
- /// adds auto-wiring to the specified types.
- /// Additionaly the creation of the types is cached when calling <see cref="CreateInstance"/> on the same instance.
- /// </summary>
- /// <param name="serviceTypes"></param>
- public void RegisterTypes(params Type[] serviceTypes)
- {
- RegisterTypes((IEnumerable<Type>) serviceTypes);
- }
-
- /// <summary>
- /// Registers the types in the IoC container and
- /// adds auto-wiring to the specified types.
- /// Additionaly the creation of the types is cached when calling <see cref="CreateInstance"/> on the same instance.
- /// </summary>
- /// <param name="serviceTypes"></param>
- public void RegisterTypes(IEnumerable<Type> serviceTypes)
- {
- foreach (var serviceType in serviceTypes)
- {
- //Don't try to register base service classes
- if (serviceType.IsAbstract || serviceType.ContainsGenericParameters)
- continue;
-
- var methodInfo = GetType().GetMethod("Register", Type.EmptyTypes);
- var registerMethodInfo = methodInfo.MakeGenericMethod(new[] { serviceType });
- registerMethodInfo.Invoke(this, new object[0]);
-
- GenerateServiceFactory(serviceType);
- }
- }
-
- private void GenerateServiceFactory(Type type)
- {
- var containerInstance = Expression.Constant(this.container);
- var resolveInstance = Expression.Call(containerInstance, "Resolve", new[] { type }, new Expression[0]);
- var resolveObject = Expression.Convert(resolveInstance, typeof(object));
- var resolveFn = Expression.Lambda<Func<object>>(resolveObject, new ParameterExpression[0]).Compile();
- this.resolveFnMap[type] = resolveFn;
- }
-
- /// <summary>
- /// Creates a new auto-wired instance of the specified type.
- /// </summary>
- /// <param name="type"></param>
- /// <returns></returns>
- public object CreateInstance(Type type)
- {
- Func<object> resolveFn;
-
- if (!this.resolveFnMap.TryGetValue(type, out resolveFn)
- && !this.container.AutoWireContainer.resolveFnMap.TryGetValue(type, out resolveFn))
- {
- throw new ResolutionException(type);
- }
-
- return resolveFn();
- }
- }
-}
View
51 src/ServiceStack/ServiceHost/ContainerResolveCache.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ServiceStack.Configuration;
+using Funq;
+using System.Linq.Expressions;
+using System.Threading;
+
+namespace ServiceStack.ServiceHost
+{
+ public class ContainerResolveCache : ITypeFactory
+ {
+ private Container container;
+ private static Dictionary<Type, Func<object>> resolveFnMap = new Dictionary<Type, Func<object>>();
+
+ public ContainerResolveCache(Container container)
+ {
+ this.container = container;
+ }
+
+ private Func<object> GenerateServiceFactory(Type type)
+ {
+ var containerInstance = Expression.Constant(this.container);
+ var resolveInstance = Expression.Call(containerInstance, "Resolve", new[] { type }, new Expression[0]);
+ var resolveObject = Expression.Convert(resolveInstance, typeof(object));
+ return Expression.Lambda<Func<object>>(resolveObject, new ParameterExpression[0]).Compile();
+ }
+
+ public object CreateInstance(Type type)
+ {
+ Func<object> resolveFn;
+ if (!resolveFnMap.TryGetValue(type, out resolveFn))
+ {
+ resolveFn = GenerateServiceFactory(type);
+
+ //Support for multiple threads is needed
+ Dictionary<Type, Func<object>> snapshot, newCache;
+ do
+ {
+ snapshot = resolveFnMap;
+ newCache = new Dictionary<Type, Func<object>>(resolveFnMap);
+ newCache[type] = resolveFn;
+ } while (!ReferenceEquals(
+ Interlocked.CompareExchange(ref resolveFnMap, newCache, snapshot), snapshot));
+ }
+
+ return resolveFn;
+ }
+ }
+}
View
73 src/ServiceStack/ServiceHost/ContainerTypeExtensions.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Funq;
+
+namespace ServiceStack.ServiceHost
+{
+ public static class ContainerTypeExtensions
+ {
+ /// <summary>
+ /// Registers the type in the IoC container and
+ /// adds auto-wiring to the specified type.
+ /// </summary>
+ /// <param name="serviceType"></param>
+ /// <param name="inFunqAsType"></param>
+ public static IRegistration RegisterAutoWiredType(this Container container, Type serviceType, Type inFunqAsType,
+ ReuseScope scope = ReuseScope.None)
+ {
+ if (serviceType.IsAbstract || serviceType.ContainsGenericParameters)
+ throw new ArgumentException("Can not register abstract/generic types!");
+
+ var methodInfo = typeof(Container).GetMethod("RegisterAutoWiredAs", Type.EmptyTypes);
+ var registerMethodInfo = methodInfo.MakeGenericMethod(new[] { serviceType, inFunqAsType });
+
+ var registration = registerMethodInfo.Invoke(container, new object[0]) as IRegistration;
+ registration.ReusedWithin(scope);
+
+ return registration;
+ }
+
+ /// <summary>
+ /// Registers the type in the IoC container and
+ /// adds auto-wiring to the specified type.
+ /// The reuse scope is set to none (transient).
+ /// </summary>
+ /// <param name="serviceTypes"></param>
+ public static void RegisterAutoWiredType(this Container container, Type serviceType)
+ {
+ //Don't try to register base service classes
+ if (serviceType.IsAbstract || serviceType.ContainsGenericParameters)
+ return;
+
+ var methodInfo = typeof(Container).GetMethod("RegisterAutoWired", Type.EmptyTypes);
+ var registerMethodInfo = methodInfo.MakeGenericMethod(new[] { serviceType });
+
+ var registration = registerMethodInfo.Invoke(container, new object[0]) as IRegistration;
+ registration.ReusedWithin(ReuseScope.None);
+ }
+
+ /// <summary>
+ /// Registers the types in the IoC container and
+ /// adds auto-wiring to the specified types.
+ /// The reuse scope is set to none (transient).
+ /// </summary>
+ /// <param name="serviceTypes"></param>
+ public static void RegisterAutoWiredTypes(this Container container, IEnumerable<Type> serviceTypes)
+ {
+ foreach (var serviceType in serviceTypes)
+ {
+ //Don't try to register base service classes
+ if (serviceType.IsAbstract || serviceType.ContainsGenericParameters)
+ continue;
+
+ var methodInfo = typeof(Container).GetMethod("RegisterAutoWired", Type.EmptyTypes);
+ var registerMethodInfo = methodInfo.MakeGenericMethod(new[] { serviceType });
+
+ var registration = registerMethodInfo.Invoke(container, new object[0]) as IRegistration;
+ registration.ReusedWithin(ReuseScope.None);
+ }
+ }
+ }
+}
View
2 src/ServiceStack/ServiceHost/ServiceController.cs
@@ -90,6 +90,8 @@ public void RegisterService(ITypeFactory serviceFactoryFn, Type serviceType)
|| service.GetGenericTypeDefinition() != typeof (IService<>)
) continue;
+ if (service.IsAbstract) continue;
+
var requestType = service.GetGenericArguments()[0];
Register(requestType, serviceType, serviceFactoryFn);
View
10 src/ServiceStack/ServiceHost/ServiceManager.cs
@@ -81,17 +81,17 @@ public ServiceManager(Container container, ServiceController serviceController)
this.ServiceController = serviceController;
}
- private AutoWireContainer typeFactory;
+ private ContainerResolveCache typeFactory;
public void Init()
{
- typeFactory = new AutoWireContainer(this.Container);
+ typeFactory = new ContainerResolveCache(this.Container);
this.ServiceController.Register(typeFactory);
ReloadServiceOperations();
- typeFactory.RegisterTypes(this.ServiceController.ServiceTypes);
+ this.Container.RegisterAutoWiredTypes(this.ServiceController.ServiceTypes);
}
public void ReloadServiceOperations()
@@ -107,7 +107,7 @@ public void RegisterService<T>()
throw new ArgumentException("Type {0} is not a Web Service that inherits IService<>".Fmt(typeof(T).FullName));
this.ServiceController.RegisterService(typeFactory, typeof(T));
- typeFactory.Register<T>();
+ this.Container.RegisterAutoWired<T>();
}
public Type RegisterService(Type serviceType)
@@ -119,7 +119,7 @@ public Type RegisterService(Type serviceType)
try
{
this.ServiceController.RegisterService(typeFactory, serviceType);
- typeFactory.RegisterTypes(serviceType);
+ this.Container.RegisterAutoWiredType(serviceType);
}
catch (Exception ex)
{
View
6 src/ServiceStack/ServiceStack.csproj
@@ -41,7 +41,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -128,6 +128,7 @@
<Compile Include="Funq\Container.Overloads.cs">
<DependentUpon>Container.cs</DependentUpon>
</Compile>
+ <Compile Include="ServiceHost\ContainerTypeExtensions.cs" />
<Compile Include="Funq\Func.cs" />
<Compile Include="Funq\IFluentInterface.cs" />
<Compile Include="Funq\IFunqlet.cs" />
@@ -178,6 +179,7 @@
<Compile Include="MiniProfiler\UI\MiniProfilerHandler.cs" />
<Compile Include="MiniProfiler\WebRequestProfilerProvider.cs" />
<Compile Include="MiniProfiler\WebRequestProfilerProvider.Settings.cs" />
+ <Compile Include="ServiceHost\ContainerResolveCache.cs" />
<Compile Include="ServiceHost\Cookies.cs" />
<Compile Include="WebHost.EndPoints\AppHostExtensions.cs" />
<Compile Include="Markdown\CachedExpressionCompiler.cs" />
@@ -202,7 +204,7 @@
<Compile Include="Markdown\ViewDataInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs" />
<Compile Include="Markdown\ITemplatePage.cs" />
- <Compile Include="ServiceHost\AutoWireContainer.cs" />
+ <Compile Include="Funq\AutoWireHelpers.cs" />
<Compile Include="ServiceHost\FileExtensions.cs" />
<Compile Include="ServiceHost\HttpFile.cs" />
<Compile Include="ServiceHost\HttpRequestAuthentication.cs" />
View
3 src/ServiceStack/WebHost.EndPoints/AppHostBase.cs
@@ -115,8 +115,7 @@ public void SetConfig(EndpointHostConfig config)
public void RegisterAs<T, TAs>() where T : TAs
{
- var autoWire = new AutoWireContainer(this.Container);
- autoWire.RegisterAs<T, TAs>();
+ this.Container.RegisterAutoWiredAs<T, TAs>();
}
public virtual void Release(object instance) { }
View
3 src/ServiceStack/WebHost.EndPoints/Support/HttpListenerBase.cs
@@ -283,8 +283,7 @@ public Container Container
public void RegisterAs<T, TAs>() where T : TAs
{
- var autoWire = new AutoWireContainer(this.Container);
- autoWire.RegisterAs<T, TAs>();
+ this.Container.RegisterAutoWiredAs<T, TAs>();
}
public virtual void Release(object instance) {}
View
3 tests/ServiceStack.ServiceHost.Tests/IoCTests.cs
@@ -21,8 +21,7 @@ public void Can_AutoWire_types_dynamically_with_expressions()
container.Register<IBar>(c => new Bar());
container.Register<int>(c => 100);
- var typeContainer = new AutoWireContainer(container);
- typeContainer.RegisterTypes(serviceType);
+ container.RegisterAutoWiredType(serviceType);
var service = container.Resolve<AutoWireService>();
View
3 tests/ServiceStack.ServiceHost.Tests/ServiceControllerPerfTests.cs
@@ -57,8 +57,7 @@ public void With_Funq_and_Expressions()
container.Register<IFoo>(c => new Foo());
container.Register<IBar>(c => new Bar());
- var funqlet = new AutoWireContainer(container);
- funqlet.RegisterTypes(typeof(AutoWireService));
+ container.RegisterAutoWiredType(typeof(AutoWireService));
Console.WriteLine("With_Funq_and_Expressions(): {0}", Measure(() => container.Resolve<AutoWireService>(), Times));
}
View
3 tests/ServiceStack.ServiceHost.Tests/ServiceHostTests.cs
@@ -69,8 +69,7 @@ public void Can_AutoWire_types_dynamically_with_expressions()
container.Register<IFoo>(c => new Foo());
container.Register<IBar>(c => new Bar());
- var typeContainer = new AutoWireContainer(container);
- typeContainer.RegisterTypes(serviceType);
+ container.RegisterAutoWiredType(serviceType);
var service = container.Resolve<AutoWireService>();
View
5 tests/ServiceStack.ServiceHost.Tests/UseCase/CustomerUseCase.cs
@@ -148,10 +148,9 @@ public static ITypeFactory GetAutoWiredFunqTypeFactory()
{
var container = GetContainerWithDependencies();
- var typeFactory = new AutoWireContainer(container);
- typeFactory.RegisterTypes(typeof(StoreCustomersService), typeof(GetCustomerService));
+ container.RegisterAutoWiredType(typeof(StoreCustomersService), typeof(GetCustomerService));
- return typeFactory;
+ return new ContainerResolveCache(container);
}
private static Container GetContainerWithDependencies()

0 comments on commit ac18dd3

Please sign in to comment.
Something went wrong with that request. Please try again.