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); }
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); }