12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- using System;
- using System.Collections.Generic;
- using System.Dynamic;
- using System.Linq.Expressions;
- using Castle.DynamicProxy;
- namespace Masuit.Tools.Dynamics;
- internal class DefaultClayActivator : IClayActivator
- {
- private static readonly IProxyBuilder Builder = new DefaultProxyBuilder();
- public dynamic CreateInstance(Type baseType, IEnumerable<IClayBehavior> behaviors, IEnumerable<object> arguments)
- {
- var isDynamicMetaObjectProvider = typeof(IDynamicMetaObjectProvider).IsAssignableFrom(baseType);
- var isClayBehaviorProvider = typeof(IClayBehaviorProvider).IsAssignableFrom(baseType);
- if (isDynamicMetaObjectProvider && isClayBehaviorProvider)
- {
- var constructorArguments = new object[]
- {
- behaviors
- };
- return Activator.CreateInstance(baseType, constructorArguments);
- }
- Func<object, object> contextualize = proxy => proxy;
- var options = new ProxyGenerationOptions();
- var constructorArgs = new List<object>();
- if (!isClayBehaviorProvider)
- {
- var mixin = new MixinClayBehaviorProvider(behaviors);
- options.AddMixinInstance(mixin);
- constructorArgs.Add(mixin);
- }
- if (!isDynamicMetaObjectProvider)
- {
- var mixin = new MixinDynamicMetaObjectProvider();
- options.AddMixinInstance(mixin);
- constructorArgs.Add(mixin);
- var prior = contextualize;
- contextualize = proxy =>
- {
- mixin.Instance = proxy;
- return prior(proxy);
- };
- }
- var proxyType = Builder.CreateClassProxyType(baseType, Type.EmptyTypes, options);
- constructorArgs.Add(new IInterceptor[]
- {
- new ClayInterceptor()
- });
- if (arguments != null)
- {
- constructorArgs.AddRange(arguments);
- }
- return contextualize(Activator.CreateInstance(proxyType, constructorArgs.ToArray()));
- }
- private class MixinClayBehaviorProvider(IEnumerable<IClayBehavior> behaviors) : IClayBehaviorProvider
- {
- IClayBehavior IClayBehaviorProvider.Behavior { get; } = new ClayBehaviorCollection(behaviors);
- }
- private class MixinDynamicMetaObjectProvider : IDynamicMetaObjectProvider
- {
- public object Instance { get; set; }
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression expression)
- {
- return new ClayMetaObject(Instance, expression);
- }
- }
- }
|