public object GetInstance(Type channel)
        {
            if (_existingChannels.ContainsKey(channel))
            {
                MethodInfo            initContext = channel.BaseType.GetProperty("Context").GetSetMethod(true);
                IChannelMethodContext context     = _contextProvider.GetDefaultContext();
                object[] mparam = new object[] { context };
                initContext.Invoke(_existingChannels[channel], mparam);
                return(_existingChannels[channel]);
            }

            ConstructorInfo ctor        = channel.GetConstructor(new Type[0]);
            string          methodName  = $"{channel.Name}Ctor";
            DynamicMethod   dynamicMtd  = new DynamicMethod(methodName, channel, new Type[0]);
            ILGenerator     iLGenerator = dynamicMtd.GetILGenerator();

            iLGenerator.Emit(OpCodes.Newobj, ctor);
            iLGenerator.Emit(OpCodes.Ret);

            ChannelObject channelObject  = (ChannelObject)dynamicMtd.CreateDelegate(typeof(ChannelObject));
            object        channelInstace = channelObject();

            PropertyInfo[] properties = channel.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (property.GetCustomAttribute <ImportedServiceAttribute>() != null)
                {
                    object service = _importResolver.GetImportedService(property.PropertyType);
                    property.SetValue(channelInstace, service);
                }
            }

            _existingChannels.Add(channel, channelInstace);
            return(channelInstace);
        }
Beispiel #2
0
        public object GetInstance(Type channel)
        {
            //If channel is already instantiated its important to change old Context to current request Context
            if (_existingChannels.ContainsKey(channel))
            {
                MethodInfo            initContext = channel.BaseType.GetProperty("Context").GetSetMethod(true);
                IChannelMethodContext context     = _contextProvider.GetDefaultContext();
                object[] mparam = new object[] { context };
                initContext.Invoke(_existingChannels[channel], mparam);
                return(_existingChannels[channel]);
            }

            //From the performance perspective its much much faster to generate instance with IL than with Activator
            ConstructorInfo ctor        = channel.GetConstructor(new Type[0]);
            string          methodName  = $"{channel.Name}Ctor";
            DynamicMethod   dynamicMtd  = new DynamicMethod(methodName, channel, new Type[0]);
            ILGenerator     iLGenerator = dynamicMtd.GetILGenerator();

            iLGenerator.Emit(OpCodes.Newobj, ctor);
            iLGenerator.Emit(OpCodes.Ret);

            ChannelObject channelObject  = (ChannelObject)dynamicMtd.CreateDelegate(typeof(ChannelObject));
            object        channelInstace = channelObject();

            //Since channels can have services that have ImportedService attribute its crucial to find them
            //so that channels dont break when trying to invoke requested service
            PropertyInfo[] properties = channel.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (property.GetCustomAttribute <ImportedServiceAttribute>() != null)
                {
                    object service = _importResolver.GetImportedService(property.PropertyType);
                    property.SetValue(channelInstace, service);
                }
            }

            _existingChannels.Add(channel, channelInstace);
            return(channelInstace);
        }
 public void SetChannelMethodContext(IChannelEndpoint endpoint, IChannelMethodContext context)
 {
     _contexts.Add(endpoint, context);
 }