//-------------------------------------------------------------------------------
// <copyright file="StandardKernel.cs" company="Ninject Project Contributors">
// Copyright (c) 2007-2009, Enkari, Ltd.
// Copyright (c) 2009-2011 Ninject Project Contributors
// Authors: Nate Kohari ([email protected])
// Remo Gloor ([email protected])
//
// Dual-licensed under the Apache License, Version 2.0, and the Microsoft Public License (Ms-PL).
// you may not use this file except in compliance with one of the Licenses.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// or
// http://www.microsoft.com/opensource/licenses.mspx
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-------------------------------------------------------------------------------
namespace Telerik.JustMock.AutoMock.Ninject
{
using System;
using Telerik.JustMock.AutoMock.Ninject.Activation;
using Telerik.JustMock.AutoMock.Ninject.Activation.Caching;
using Telerik.JustMock.AutoMock.Ninject.Activation.Strategies;
using Telerik.JustMock.AutoMock.Ninject.Components;
using Telerik.JustMock.AutoMock.Ninject.Injection;
using Telerik.JustMock.AutoMock.Ninject.Modules;
using Telerik.JustMock.AutoMock.Ninject.Planning;
using Telerik.JustMock.AutoMock.Ninject.Planning.Bindings.Resolvers;
using Telerik.JustMock.AutoMock.Ninject.Planning.Strategies;
using Telerik.JustMock.AutoMock.Ninject.Selection;
using Telerik.JustMock.AutoMock.Ninject.Selection.Heuristics;
/// <summary>
/// The standard implementation of a kernel.
/// </summary>
public class StandardKernel : KernelBase
{
/// <summary>
/// Initializes a new instance of the <see cref="StandardKernel"/> class.
/// </summary>
/// <param name="modules">The modules to load into the kernel.</param>
public StandardKernel(params INinjectModule[] modules) : base(modules)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="StandardKernel"/> class.
/// </summary>
/// <param name="settings">The configuration to use.</param>
/// <param name="modules">The modules to load into the kernel.</param>
public StandardKernel(INinjectSettings settings, params INinjectModule[] modules) : base(settings, modules)
{
}
/// <summary>
/// Gets the kernel.
/// </summary>
/// <value>The kernel.</value>
protected override IKernel KernelInstance
{
get
{
return this;
}
}
protected virtual bool ShouldAddComponent(Type component, Type implementation)
{
return true;
}
private void AddComponent<TComponent, TImplementation>()
where TComponent : INinjectComponent
where TImplementation : TComponent, INinjectComponent
{
if (ShouldAddComponent(typeof(TComponent), typeof(TImplementation)))
{
Components.Add<TComponent, TImplementation>();
}
}
/// <summary>
/// Adds components to the kernel during startup.
/// </summary>
protected override void AddComponents()
{
AddComponent<IPlanner, Planner>();
AddComponent<IPlanningStrategy, ConstructorReflectionStrategy>();
AddComponent<IPlanningStrategy, PropertyReflectionStrategy>();
AddComponent<IPlanningStrategy, MethodReflectionStrategy>();
AddComponent<ISelector, Selector>();
AddComponent<IConstructorScorer, StandardConstructorScorer>();
AddComponent<IInjectionHeuristic, StandardInjectionHeuristic>();
AddComponent<IPipeline, Pipeline>();
if (!Settings.ActivationCacheDisabled)
{
AddComponent<IActivationStrategy, ActivationCacheStrategy>();
}
AddComponent<IActivationStrategy, PropertyInjectionStrategy>();
AddComponent<IActivationStrategy, MethodInjectionStrategy>();
AddComponent<IActivationStrategy, InitializableStrategy>();
AddComponent<IActivationStrategy, StartableStrategy>();
AddComponent<IActivationStrategy, BindingActionStrategy>();
AddComponent<IActivationStrategy, DisposableStrategy>();
AddComponent<IBindingResolver, StandardBindingResolver>();
AddComponent<IBindingResolver, OpenGenericBindingResolver>();
AddComponent<IMissingBindingResolver, DefaultValueBindingResolver>();
AddComponent<IMissingBindingResolver, SelfBindingResolver>();
#if !NO_LCG
if (!Settings.UseReflectionBasedInjection)
{
AddComponent<IInjectorFactory, DynamicMethodInjectorFactory>();
}
else
#endif
{
AddComponent<IInjectorFactory, ReflectionInjectorFactory>();
}
AddComponent<ICache, Cache>();
AddComponent<IActivationCache, ActivationCache>();
AddComponent<ICachePruner, GarbageCollectionCachePruner>();
#if !NO_ASSEMBLY_SCANNING
AddComponent<IModuleLoader, ModuleLoader>();
AddComponent<IModuleLoaderPlugin, CompiledModuleLoaderPlugin>();
AddComponent<IAssemblyNameRetriever, AssemblyNameRetriever>();
#endif
}
}
}
/*
JustMock Lite
Copyright © 2020 Progress Software Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using Telerik.JustMock.AutoMock.Ninject;
using Telerik.JustMock.AutoMock.Ninject.Infrastructure.Disposal;
using Telerik.JustMock.AutoMock.Ninject.Modules;
using Telerik.JustMock.AutoMock.Ninject.Parameters;
#if !PORTABLE
namespace Telerik.JustMock.Plugins
{
internal class PluginsRegistry : DisposableObject
{
private Dictionary<Type, INinjectModule> plugins = new Dictionary<Type, INinjectModule>();
private readonly StandardKernel kernel = new StandardKernel();
public PluginT Register<PluginT>(string assemblyPath, params IParameter[] parameters)
where PluginT : INinjectModule
{
lock (this)
{
var assembly = Assembly.LoadFile(assemblyPath);
this.kernel.Load(assembly);
var plugin = this.kernel.TryGet<PluginT>(parameters);
if (plugin == null)
{
throw new NotSupportedException(string.Format("Plugin type {0} not found, lookup assembly {1}", typeof(PluginT), assembly));
}
plugins.Add(typeof(PluginT), plugin);
return plugin;
}
}
public bool Exists<PluginT>() where PluginT : INinjectModule
{
lock (this)
{
return plugins.ContainsKey(typeof(PluginT));
}
}
public PluginT Get<PluginT>() where PluginT : INinjectModule
{
lock (this)
{
return (PluginT)plugins[typeof(PluginT)];
}
}
public PluginT Unregister<PluginT>() where PluginT : INinjectModule
{
lock (this)
{
INinjectModule plugin = null;
if (plugins.TryGetValue(typeof(PluginT), out plugin))
{
var pluginDisposable = plugin as IDisposable;
if (pluginDisposable != null)
{
pluginDisposable.Dispose();
}
}
return (PluginT)plugin;
}
}
public override void Dispose(bool disposing)
{
lock (this)
{
if (disposing && !this.IsDisposed)
{
foreach (var plugin in plugins.Values)
{
var pluginDisposable = plugin as IDisposable;
if (pluginDisposable != null)
{
pluginDisposable.Dispose();
}
}
}
base.Dispose(disposing);
}
}
}
}
#endif
/*
JustMock Lite
Copyright © 2010-2015,2018-2019 Progress Software Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Telerik.JustMock.AutoMock.Ninject;
using Telerik.JustMock.AutoMock.Ninject.Planning.Bindings.Resolvers;
using Telerik.JustMock.AutoMock.Ninject.Syntax;
using Telerik.JustMock.Core;
using Telerik.JustMock.Core.Castle.DynamicProxy;
using Telerik.JustMock.Core.Context;
using Telerik.JustMock.Expectations;
using Telerik.JustMock.Helpers;
namespace Telerik.JustMock.AutoMock
{
/// <summary>
/// Auto-mocking container that can automatically inject mocks for all
/// dependencies of the tested class. The container is based on NInject and
/// supports the core NInject syntax as well as syntax extensions for arranging
/// mocks and injecting mocks into properties and constructor arguments.
/// </summary>
/// <typeparam name="T">The type of the class whose dependencies should be mocked.
/// If this is an abstract class, then a Behavior.CallOriginal mock is created for the instance.
/// Abstract members of the instance can be manipulated using the methods in the Mock class.
/// </typeparam>
public sealed class MockingContainer<T> : StandardKernel where T : class
{
private T resolvedInstance;
private IMockResolver mockResolver;
/// <summary>
/// Initializes a new instance of the <see cref="MockingContainer{T}" /> class.
/// </summary>
/// <param name="settings">Optional settings that modify the way the auto-mocking container works.</param>
public MockingContainer(AutoMockSettings settings = null)
: base(settings ?? new AutoMockSettings())
{
}
/// <summary>
/// Implementation detail.
/// </summary>
protected override bool ShouldAddComponent(Type component, Type implementation)
{
if (implementation == typeof(SelfBindingResolver))
{
return false;
}
return base.ShouldAddComponent(component, implementation);
}
/// <summary>
/// Implementation detail.
/// </summary>
protected override void AddComponents()
{
base.AddComponents();
this.Components.Add<IMissingBindingResolver, MockResolver>();
this.Components.Add<IMockResolver, MockResolver>();
this.mockResolver = this.Components.Get<IMockResolver>();
if (Settings.ConstructorArgTypes == null)
{
this.Bind<T>().To(this.ImplementationType);
}
else
{
this.Bind<T>().ToConstructor(CreateConstructorExpression());
}
}
private Type implementationType;
private Type ImplementationType
{
get
{
if (this.implementationType == null)
{
var targetType = typeof(T);
if (targetType.IsAbstract)
{
MockCreationSettings settings = MockCreationSettings.GetSettings(Behavior.CallOriginal);
ProxyTypeInfo typeInfo = MockingContext.CurrentRepository.CreateClassProxyType(targetType, settings);
this.implementationType = typeInfo.ProxyType;
foreach (var mixin in typeInfo.Mixins)
{
this.Bind(mixin.Key).ToConstant(mixin.Value);
}
}
else
{
this.implementationType = targetType;
}
}
return this.implementationType;
}
}
/// <summary>
/// Gets the kernel settings.
/// </summary>
public new AutoMockSettings Settings
{
get { return ProfilerInterceptor.GuardInternal(() => (AutoMockSettings)base.Settings); }
}
private Expression<Func<IConstructorArgumentSyntax, T>> CreateConstructorExpression()
{
var argTypes = Settings.ConstructorArgTypes;
var constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, argTypes, null);
if (constructor == null)
throw new MockException("Constructor with the following parameter types was not found: " + ", ".Join(argTypes));
if (!constructor.IsPublic && !constructor.IsFamily && !constructor.IsFamilyOrAssembly)
throw new MockException("Constructor is not accessible by derived types.");
var implType = this.ImplementationType;
if (implType.IsProxy())
{
constructor = implType.GetConstructors()
.Single(ctor => ctor.GetParameters()
.Select(p => p.ParameterType)
.SkipWhile(pt => pt != typeof(IInterceptor[]))
.Skip(1)
.SequenceEqual(argTypes));
}
var inject = typeof(IConstructorArgumentSyntax).GetMethod("Inject");
var x = Expression.Parameter(typeof(IConstructorArgumentSyntax), "x");
var expr = Expression.New(constructor,
constructor.GetParameters().Select(p => Expression.Call(x, inject.MakeGenericMethod(p.ParameterType))).ToArray());
return (Expression<Func<IConstructorArgumentSyntax, T>>)Expression.Lambda(typeof(Func<IConstructorArgumentSyntax, T>), expr, x);
}
/// <summary>
/// Resolves the instance of the underlying type with all dependencies injected.
/// </summary>
public T Instance
{
get
{
return ProfilerInterceptor.GuardInternal(() =>
{
if (resolvedInstance == null)
{
resolvedInstance = this.Get<T>();
}
return resolvedInstance;
});
}
}
/// <summary>
/// Entry-point for setting expectations.
/// </summary>
/// <typeparam name="TInterface">Mocking interface</typeparam>
/// <param name="expression">Target expression</param>
/// <returns>
/// Reference to <see cref="FuncExpectation{TResult}"/> to setup the mock.
/// </returns>
public FuncExpectation<object> Arrange<TInterface>(Expression<Func<TInterface, object>> expression)
{
return ProfilerInterceptor.GuardInternal(() => this.Get<TInterface>().Arrange(expression));
}
/// <summary>
/// Entry-point for setting expectations.
/// </summary>
/// <typeparam name="TInterface">
/// Mocking interface
/// </typeparam>
/// <param name="expression">Target expression</param>
/// <returns>
/// Reference to <see cref="ActionExpectation"/> to setup the mock.
/// </returns>
public ActionExpectation Arrange<TInterface>(Expression<Action<TInterface>> expression)
{
return ProfilerInterceptor.GuardInternal(() => this.Get<TInterface>().Arrange(expression));
}
/// <summary>
/// Entry-point for setting expectations.
/// </summary>
/// <typeparam name="TInterface">
/// Mocking interface
/// </typeparam>
/// <param name="action">Target action</param>
/// <returns>
/// Reference to <see cref="ActionExpectation"/> to setup the mock.
/// </returns>
public ActionExpectation ArrangeSet<TInterface>(Action<TInterface> action)
{
return ProfilerInterceptor.GuardInternal(() => this.Get<TInterface>().ArrangeSet(action));
}
/// <summary>
/// Asserts all expected setups.
/// </summary>
/// <param name="message">A message to display if the assertion fails.</param>
public void AssertAll(string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.mockResolver.ForEachMock(mock => mock.AssertAll(message)));
}
/// <summary>
/// Asserts all expected calls that are marked as must or
/// to be occurred a certain number of times.
/// </summary>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert(string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.mockResolver.ForEachMock(mock => mock.Assert(message)));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
/// <param name="expression">Target expression.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(Expression<Action<TService>> expression, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().Assert(expression, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
/// <param name="expression">Target expression</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(Expression<Func<TService, object>> expression, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().Assert(expression, message));
}
/// <summary>
/// Asserts a specific dependency
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
public void Assert<TService>()
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().Assert());
}
/// <summary>
/// Asserts a specific dependency
/// </summary>
/// <param name="bindingName">Name.</param>
/// <param name="message">A message to display if the assertion fails.</param>
/// <typeparam name="TService">Service Type.</typeparam>
public void Assert<TService>(string bindingName, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>(bindingName).Assert(message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="expression">Target expression.</param>
/// <param name="occurs">Specifies the number of times a mock call should occur.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(Expression<Func<TService, object>> expression, Occurs occurs, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().Assert(expression, occurs, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="expression">Target expression</param>
/// <param name="occurs">Specifies the number of times a mock call should occur.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(Expression<Action<TService>> expression, Occurs occurs, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().Assert(expression, occurs, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="bindingName">Name.</param>
/// <param name="expression">Target expression.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(string bindingName, Expression<Func<TService, object>> expression, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>(bindingName).Assert(expression, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="bindingName">Name.</param>
/// <param name="expression">Target expression.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(string bindingName, Expression<Action<TService>> expression, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>(bindingName).Assert(expression, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="bindingName">Name.</param>
/// <param name="expression">Target expression.</param>
/// <param name="occurs">Specifies the number of times a mock call should occur.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(string bindingName, Expression<Func<TService, object>> expression, Occurs occurs, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>(bindingName).Assert(expression, occurs, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service Type.</typeparam>
/// <param name="bindingName">Name.</param>
/// <param name="expression">Target expression.</param>
/// <param name="occurs">Specifies the number of times a mock call should occur.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void Assert<TService>(string bindingName, Expression<Action<TService>> expression, Occurs occurs, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>(bindingName).Assert(expression, occurs, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
/// <param name="action">Target action.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void AssertSet<TService>(Action<TService> action, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().AssertSet(action, message));
}
/// <summary>
/// Asserts the specific call
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
/// <param name="action">Target action.</param>
/// <param name="occurs">Specifies the number of times a mock call should occur.</param>
/// <param name="message">A message to display if the assertion fails.</param>
public void AssertSet<TService>(Action<TService> action, Occurs occurs, string message = null)
{
ProfilerInterceptor.GuardInternal(() => this.Get<TService>().AssertSet(action, occurs, message));
}
}
}