( "" Unity), ChannelFactory - , , , โโ , . (. .)
, -, . - , . ( ), : var client = SoapClientInterceptorBehavior<T>.CreateInstance(new ChannelFactory<T>("*")), . var myClass = new MyClass(SoapClientInterceptorBehavior<IServiceClient>.CreateInstance(new ChannelFactory<IServiceClient>("*"))); (, , , factory , IServiceClient , .; -))
, - .
public class SoapClientInterceptorBehavior<T> : IInterceptionBehavior
{
private static readonly Logger Logger = LogManager.GetLogger(LoggerName());
private static string LoggerName()
{
string baseName = MethodBase.GetCurrentMethod().DeclaringType.FullName;
baseName = baseName.Remove(baseName.IndexOf('`'));
return baseName + "." + typeof(T).Name;
}
private readonly Func<T> _clientCreator;
public SoapClientInterceptorBehavior(ChannelFactory<T> channelFactory)
: this(channelFactory.CreateChannel)
{
}
public SoapClientInterceptorBehavior(Func<T> clientCreationFunc)
{
_clientCreator = clientCreationFunc;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Logger.Info(() => "Invoking method: " + input.MethodBase.Name + "()");
T client = _clientCreator.Invoke();
Logger.Trace(() => "Created client");
var channel = client as IClientChannel;
IMethodReturn result;
int size = input.Arguments.Count;
var args = new object[size];
for(int i = 0; i < size; i++)
{
args[i] = input.Arguments[i];
}
Logger.Trace(() => "Arguments: " + string.Join(", ", args));
try
{
object val = input.MethodBase.Invoke(client, args);
if (Logger.IsTraceEnabled)
{
Logger.Trace(() => "Completed " + input.MethodBase.Name + "(" + string.Join(", ", args) + ") return-value: " + val);
}
else if (Logger.IsDebugEnabled)
{
Logger.Debug(() => "Completed " + input.MethodBase.Name + "(" + string.Join(", ", args) + ")");
}
else
{
Logger.Info(() => "Completed " + input.MethodBase.Name + "()");
}
result = input.CreateMethodReturn(val, args);
if (channel != null)
{
Logger.Trace("Closing channel");
channel.Close();
}
}
catch (TargetInvocationException tie)
{
result = HandleException(input, args, tie.InnerException, channel);
}
catch (Exception e)
{
result = HandleException(input, args, e, channel);
}
return result;
}
private static IMethodReturn HandleException(IMethodInvocation input, object[] args, Exception e, IClientChannel channel)
{
if (Logger.IsWarnEnabled)
{
string msg = string.Format("Exception from " + input.MethodBase.Name + "(" + string.Join(", ", args) + ")");
Logger.Warn(msg, e);
}
IMethodReturn result = input.CreateExceptionMethodReturn(e);
if (channel != null)
{
Logger.Trace("Aborting channel");
channel.Abort();
}
return result;
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return new [] { typeof(T) };
}
public bool WillExecute
{
get { return true; }
}
public static T CreateInstance(ChannelFactory<T> factory)
{
IInterceptionBehavior behavior = new SoapClientInterceptorBehavior<T>(factory);
return (T)Intercept.ThroughProxy<IMy>(
new MyClass(),
new InterfaceInterceptor(),
new[] { behavior });
}
public class MyClass : IMy
{
}
public interface IMy
{
}
}