Using raw types in C#? - c#

Can I use raw type in C# like Java or is there a workaround for this? I know using Raw Type in Java is bad practice but that can solve my current problem.
I have an object that has a field holding a Pool, so that it can return to that Pool whenever it's done with its job.
//C#
public class MyObject : IPoolable
{
public Pool<MyObject> pool;
}
But if there is a new kind of object (ex: MovableObject), I want my pool field has Pool<MovableObject> not Pool<MyObject>. (There are also many kinds of objects derived from MovableObject or MyObject).
In Java, I could define pool field a raw type of Pool so that there is no compiling error.
//Java
public class MyObject implements IPoolable
{
public Pool pool;
}
I'm using a method to return all kinds sof objects in both versions. In Java, it works well but in C#, it has compiling error.
//Java
static public <T extends MyObject> T createObject(Class<T> type) {
Pool<T> pool = Pools.get(type);
T obj= pool.obtain();
obj.setPool(pool); //This won't have any problem since it is raw type
return obj;
}
//C#
public static T CreateObject<T>() where T : MyObject
{
Pool<T> pool = Pools.GetPool<T>();
T obj= pool.Obtain();
obj.Pool = pool; //Error: cannot convert Pool<T> to Pool<MyAction>
return obj;
}
Edit 1: Providing other classes and Minimal, Reproducible Example
public interface IPoolable
{
void Reset();
}
public abstract class Pool<T> where T : IPoolable
{
private readonly Stack<T> freeObjects = new Stack<T>();
public Pool() { }
protected abstract T InstantiateObject(object[] args);
public T Obtain(object[] args = null)
{
return freeObjects.Count == 0 ? InstantiateObject(args) : freeObjects.Pop();
}
public void Free(T obj)
{
if (obj != null)
{
freeObjects.Push(obj);
Reset(obj);
}
}
protected virtual void Reset(T obj)
{
obj.Reset();
}
public void Clear()
{
freeObjects.Clear();
}
}
//ReflectionPool
public class ReflectionPool<T> : Pool<T> where T : IPoolable
{
public ReflectionPool() : base()
{
}
protected override T InstantiateObject(object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
}
public class Pools
{
static private readonly Dictionary<Type, object> typePools = new Dictionary<Type, object>();
static public Pool<T> GetPool<T>(int max) where T : IPoolable
{
Type type = typeof(T);
if (!typePools.TryGetValue(type, out object pool))
{
pool = new ReflectionPool<T>();
typePools.Add(type, pool);
}
return (Pool<T>)pool;
}
static public Pool<T> GetPool<T>() where T : IPoolable
{
return GetPool<T>(100);
}
}
So in MyObject class, there is a method making my object doing something, after completing it, the current object need to be returned to Pool
//Base Object
public abstract class MyObject : IPoolable
{
public Pool<MyObject> pool; //This is still a problem
public void CallMe()
{
if (Act()) //If this object completing acting
{
ToPool();
}
}
public abstract bool Act();
public void ToPool()
{
pool.Free(this);
pool = null;
}
public abstract void Reset();
}
//Movable Object
public class MovableObject : MyObject
{
//public Pool<MyObject> pool; //Put this here as comment because I want it become Pool<MovableObject>
public override bool Act()
{
return true; //Return false if not reach destination
}
public override void Reset() { }
public override string ToString()
{
return "Movable";
}
}
//I'm using this class for create object I want
public class ObjectFactory
{
public static T CreateObject<T>() where T : MyObject
{
Pool<T> pool = Pools.GetPool<T>();
if(pool != null)
{
T obj = pool.Obtain();
obj.pool = pool; //Error here: Cannot implicitly convert type 'Pool<T>' to 'Pool<MyObject>'
return obj;
}
return null;
}
public static MovableObject MovableObject()
{
return CreateObject<MovableObject>();
}
}
Edit 2: Re-Updated code in edit 1

Related

How to override a static method from a DLL Export

I want to override a static method from a DLL Export
public class Export {
[DllExport] public static string plugin_name() { return Plugin.Instance.plugin_name(); }
}
public class Plugin<T> where T: Plugin<T>, new()
{
private static readonly Lazy<T> val = new Lazy<T>(() => new T());
public static T Instance { get { return val.Value; } }
protected Plugin() { }
public new static string plugin_name() { }
}
}
so these classes are in a dll file now I want that people who use the dll only do that in the main class.
public class Main : Plugin<Main> {
public override string plugin_name() {
return "a test plugin";
}
}
I have tested it for hours but failed.
You can not override static methods. You need to make a virtual or abstract instance method.
public abstract class Plugin<T> where T : new()
{
private static readonly Lazy<T> val = new Lazy<T>(() => new T());
public static T Instance { get { return val.Value; } }
protected Plugin() { }
public abstract string plugin_name();
}
public class Main : Plugin<Main> {
public override string plugin_name() => "a test plugin";
}
To make the method plugin_name static also does not make much sense, since you anyway create a singleton instance.
You can check out the code here.

How to Correctly Invoke WCF ServiceClient Proxy Extensions?

While troubleshooting a wcf client issue I came across some code from #marc-gravell here. I read the article a number of times and then decided to try and see if I could use the code for real so I created a console app and pulled it all in.
Wrapper:
public interface IDisposableWrapper<T> : IDisposable
{
T BaseObject { get; }
}
public class DisposableWrapper<T> : IDisposableWrapper<T> where T : class, IDisposable
{
public T BaseObject { get; private set; }
public DisposableWrapper(T baseObject) { BaseObject = baseObject; }
protected virtual void OnDispose()
{
BaseObject.Dispose();
}
public void Dispose()
{
if (BaseObject != null)
{
try
{
OnDispose();
}
catch
{
// swallow...
}
}
BaseObject = null;
}
}
Extensions:
public static class DisposableExtensions
{
// core "just dispose it without barfing"
public static IDisposableWrapper<T> Wrap<T>(this T baseObject)
where T : class, IDisposable
{
if (baseObject is IDisposableWrapper<T>) return (IDisposableWrapper<T>)baseObject;
return new DisposableWrapper<T>(baseObject);
}
// specific handling for service-model
public static IDisposableWrapper<TProxy> Wrap<TProxy, TChannel>(this TProxy proxy)
where TProxy : ClientBase<TChannel>
where TChannel : class
{
return new ClientWrapper<TProxy, TChannel>(proxy);
}
}
ClientWrapper:
public class ClientWrapper<TProxy, TChannel> : DisposableWrapper<TProxy>
where TProxy : ClientBase<TChannel>
where TChannel : class
{
public ClientWrapper(TProxy proxy) : base(proxy)
{
}
protected override void OnDispose()
{
// lots of code per state of BaseObject
//State != CommunicationState.Faulted;
}
}
Now, when I go to use it, I have this:
static void Main(string[] args)
{
using (var proxy = new PLPlacementServiceClient())
{
var result = proxy.GetDocumentClassForNewBusiness();
}
using (var proxy = new PLPlacementServiceClient().Wrap())
{
var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
}
using (var proxy = new PLPlacementServiceClient().Wrap<>())//what goes here?
{
var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
}
}
When I F-12 the PLPlacementServiceClient().Wrap() method , it takes me to the non-generic implementation in the extensions class
IDisposableWrapper<T> Wrap<T>(this T baseObject)
, but I was expecting to be taken to the other signature
IDisposableWrapper<TProxy> Wrap<TProxy, TChannel>(this TProxy proxy)
So here is my question(s), "How do I invoke the ClientBase version of the extension?"
Thank you,
Stephen
You must specify both type parameters for method Wrap. That is:
using (var proxy = new PLPlacementServiceClient().Wrap<PLPlacementServiceClient,/*type of the service contract PLPlacementServiceClient is implementing*/>())
{
var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
}

Is this the only way to have the functionality of abstract static methods?

I'm working on a framework right now and the motto is "no redundancy" and "I don't want to know the vendor specifics" so most things are handled through Interfaces and Generic classes. Now I had the situation where I have an abstract class that wants to match things depending on it's own Enum variable se but it shouldn't have to know how the vendor provides a relatable variable to be matched to se. The vendor could have decided an integer, an Enum or a string would be the best to save that information but honestly I don't want to know.
So I thought well no problem have an abstract static method that must be provided by every implementation of a wrapper to compare se with the vendor specific way of saving that information.
//The original version I wanted to be possible
public abstract class AbstractGenericClass<TWrapper<T>, T> where TWrapper : AbstractGenericWrapper<T> {
protected TWrapper tWrapper;
//our SomeEnum se is somehow relatable to every T
//but we don't want to know how
protected SomeEnum se = ...;
//called on Start
public void Start() {
List<T> ts = FindObjectsOfType<T>;
foreach (T t in ts) {
if(T.Compare(t, this.se)) {
tWrapper = new TWrapper(t);
}
}
}
}
public abstract class AbstractGenericWrapper<T> {
T _t;
public AbstractGenericWrapper(T t) {
_t = t;
}
public static abstract bool Compare(T t, SomeEnum someEnum);
}
public class ConcreteNongenericWrapper : AbstractGenericWrapper<VendorSpecificImplementation> {
public static bool Compare(VendorSpecificImplementation t, SomeEnum someEnum) {
return t.vendorVariable.toLower().Equals(Enum.GetValues(typeof(someEnum), someEnum));
}
}
public class OtherConcreteNongenericWrapper : AbstractGenericWrapper<OtherVendorSpecificImplementation> {
public static bool Compare(OtherVendorSpecificImplementation t, SomeEnum someEnum) {
return t.otherVendorVariable % 3 == (int) someEnum;
}
}
public class SomeImplementation {
public static void main() {
AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric> foo
= new AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric>();
AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric> bar
= new AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric>();
foo.Start();
bar.Start();
}
}
I found out that that isn't possible and I wanted to know if this version down below is the best/only way of doing it? It has redundancy and I don't like it and it is longer.
//An attempt at a solution:
public abstract class AbstractGenericClass<TWrapper<T>, T> where TWrapper : AbstractGenericWrapper<T> {
protected TWrapper tWrapper;
//our SomeEnum se is somehow relatable to every T
//but we don't want to know how
protected SomeEnum se = ...;
//called on start
public abstract void Start();
}
public abstract class AbstractGenericWrapper<T> {
T _t;
public AbstractGenericWrapper(T t) {
_t = t;
}
}
public class ConcreteNongenericClass : AbstractGenericClass<VendorSpecificImplementation> {
//called on start
public override void Start() {
List<VendorSpecificImplementation> ts = FindObjectsOfType<VendorSpecificImplementation>;
foreach (VendorSpecificImplementation t in ts) {
if(t.vendorVariable.toLower().Equals(Enum.GetValues(typeof(someEnum), someEnum))) {
tWrapper = new ConcreteNongenericWrapper(t);
}
}
}
}
public class ConcreteNongenericWrapper : AbstractGenericWrapper<VendorSpecificImplementation> {
}
public class OtherConcreteNongenericClass : AbstractGenericClass<OtherVendorSpecificImplementation> {
//called on start
public void Start() {
List<OtherVendorSpecificImplementation> ts = FindObjectsOfType<OtherVendorSpecificImplementation>;
foreach (OtherVendorSpecificImplementation t in ts) {
if(t.otherVendorVariable % 3 == (int) someEnum) {
tWrapper = new OtherConcreteNongenericWrapper(t);
}
}
}
}
public class OtherConcreteNongenericWrapper : AbstractGenericWrapper<OtherVendorSpecificImplementation> {
}
public class SomeImplementation {
public static void main() {
AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric> foo
= new AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric>();
AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric> bar
= new AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric>();
foo.Start();
bar.Start();
}
}
Thank you very much for your time and help!

Intercepting method calls in C# using Proxies

What I'm trying to do is to be able to intercept calls to an object's methods and properties for cross-cutting concerns. I'm using proxy-based AOP using ContextBoundObject.
However this doesn't work for recursive method calls, The first call against the target will be intercepted by the proxy and successfully invoked, allowing me to do cross-cut here. However subsequent method calls from within the first method will stay within the target class and are not intercepted by the proxy as if no marshaling occurs!
Is there any way I can make it work? (I'm trying to avoid third-party libraries like PostSharp, Unity or Spring.Net)
class Program
{
static void Main(string[] args)
{
var t = new SimpleObject();
t.TestMethod1();
}
}
[Intercept]
class SimpleObject : ContextBoundObject
{
public string TestMethod1()
{
return TestMethod2();
}
public string TestMethod2()
{
return "test";
}
}
[AttributeUsage(AttributeTargets.Class)]
public class InterceptAttribute : ContextAttribute, IContributeObjectSink
{
public InterceptAttribute()
: base("Intercept")
{ }
public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
return false;
}
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
return new InterceptSink(nextSink);
}
}
public class InterceptSink : IMessageSink
{
public IMessageSink NextSink { get; private set; }
public InterceptSink(IMessageSink nextSink)
{
this.NextSink = nextSink;
}
public IMessage SyncProcessMessage(IMessage msg)
{
IMethodCallMessage mcm = (msg as IMethodCallMessage);
// { cross-cut here }
IMessage rtnMsg = this.NextSink.SyncProcessMessage(msg);
IMethodReturnMessage mrm = (rtnMsg as IMethodReturnMessage);
// { cross-cut here }
return mrm;
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return null;
}
}
C# designers have never been in favor of AOP, there's no easy way to intercept method calls without using Proxies and Marshaling, which have their own drawbacks!
In case anyone wants to intercept method/property calls (eg. cross cutting concerns), I've found RealProxy to be of some help.
RealProxy From MSDN:
A client that uses an object across any kind of a remoting boundary is
actually using a transparent proxy for the object. The transparent
proxy provides the illusion that the actual object resides in the
client's space. It achieves this by forwarding calls made on it to the
real object using the remoting infrastructure.
Note: A type being proxied using RealProxy must be either an interface or inherit from MarshalByRefObject.
Here's some implementation of RealProxy using a Factory Method to create a proxy of an object at runtime:
public abstract class RuntimeProxy
{
public static readonly object Default = new object();
public static Target Create<Target>(Target instance, RuntimeProxyInterceptor interceptor) where Target : class
{
return (Target)new InternalProxy<Target>(instance, interceptor).GetTransparentProxy();
}
public static Target Create<Target>(Target instance, Func<RuntimeProxyInvoker, object> factory) where Target : class
{
return (Target)new InternalProxy<Target>(instance, new InternalRuntimeProxyInterceptor(factory)).GetTransparentProxy();
}
class InternalProxy<Target> : RealProxy where Target : class
{
readonly object Instance;
readonly RuntimeProxyInterceptor Interceptor;
public InternalProxy(Target instance, RuntimeProxyInterceptor interceptor)
: base(typeof(Target))
{
Instance = instance;
Interceptor = interceptor;
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = (IMethodCallMessage)msg;
var method = (MethodInfo)methodCall.MethodBase;
try
{
var result = Interceptor.Invoke(new InternalRuntimeProxyInterceptorInvoker(Instance, method, methodCall.InArgs));
if (result == RuntimeProxy.Default)
result = method.ReturnType.IsPrimitive ? Activator.CreateInstance(method.ReturnType) : null;
return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
}
catch (Exception ex)
{
if (ex is TargetInvocationException && ex.InnerException != null)
return new ReturnMessage(ex.InnerException, msg as IMethodCallMessage);
return new ReturnMessage(ex, msg as IMethodCallMessage);
}
}
}
class InternalRuntimeProxyInterceptor : RuntimeProxyInterceptor
{
readonly Func<RuntimeProxyInvoker, object> Factory;
public InternalRuntimeProxyInterceptor(Func<RuntimeProxyInvoker, object> factory)
{
this.Factory = factory;
}
public override object Invoke(RuntimeProxyInvoker invoker)
{
return Factory(invoker);
}
}
class InternalRuntimeProxyInterceptorInvoker : RuntimeProxyInvoker
{
public InternalRuntimeProxyInterceptorInvoker(object target, MethodInfo method, object[] args)
: base(target, method, args)
{ }
}
}
public abstract class RuntimeProxyInterceptor
{
public virtual object Invoke(RuntimeProxyInvoker invoker)
{
return invoker.Invoke();
}
}
public abstract class RuntimeProxyInvoker
{
public readonly object Target;
public readonly MethodInfo Method;
public readonly ReadOnlyCollection<object> Arguments;
public RuntimeProxyInvoker(object target, MethodInfo method, object[] args)
{
this.Target = target;
this.Method = method;
this.Arguments = new ReadOnlyCollection<object>(args);
}
public object Invoke()
{
return Invoke(this.Target);
}
public object Invoke(object target)
{
if (target == null)
throw new ArgumentNullException("target");
try
{
return this.Method.Invoke(target, this.Arguments.ToArray());
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
}
}
You can use the RuntimeProxy as a factory to create a proxy of an object and intercept all method/property calls and invoke the actual method.
Here's a sample:
class SomeClass : MarshalByRefObject
{
public int Mul(int a, int b)
{
return a * b;
}
public void SetValue(int val)
{
this.Val = val;
}
public int Val { get; set; }
}
Use RuntimeProxy class to create a proxy for an instance of the SomeClass class and intercept the calls:
var test = new SomeClass();
var proxy = RuntimeProxy.Create(test, t =>
{
// cross-cut here
return t.Invoke(); // invoke the actual call
});
var res = proxy.Mul(3, 4); // method with return value
proxy.SetValue(2); // void method, setting some property
var val = proxy.Val; // property access
You could use interface types in case you don't want to inherit from MarshalByRefObject class.

Modify existing WCF communication object

This is how I used to make method calls:
SvcHelper.Using<SomeWebServiceClient>(proxy =>
{
proxy.SomeMethod();
}
public class SvcHelper
{
public static void Using<TClient>(Action<TClient> action) where TClient : ICommunicationObject, IDisposable, new()
{
}
}
This is how I make method calls:
ChannelFactory<ISomethingWebService> cnFactory = new ChannelFactory<ISomethingWebService>("SomethingWebService");
ISomethingWebService client = cnFactory.CreateChannel();
using (new OperationContextScope((IContextChannel)client))
{
client.SomeMethod();
}
My question is: Instead of replacing every instance of my original method call approach; Is there a way to modify my SvcHelper and do the creation of the channel in the SvcHelper constructor and then simply pass the interface like the following:
SvcHelper.Using<ISomethingWebService>(client =>
{
client.SomeMethod();
}
Hope this makes sense and thanks in advance.
First, you don't want to create a new ChannelFactory<T> every call to the Using helper method. They are the most costly thing to construct in the WCF universe. So, at bare minimum, you will want to use a caching approach there.
Second, you don't want to tie yourself to "client" types at all anymore. Just work straight with the service contract interfaces.
Starting from what you've got, here's where I'd go based on how I've done this in the past:
public class SvcHelper
{
private static ConcurrentDictionary<ChannelFactoryCacheKey, ChannelFactory> ChannelFactories = new ConcurrentDictionary<ChannelFactoryCacheKey, ChannelFactory>();
public static void Using<TServiceContract>(Action<TServiceContract> action) where TServiceContract : class
{
SvcHelper.Using<TServiceContract>(action, "*");
}
public static void Using<TServiceContract>(Action<TServiceContract> action, string endpointConfigurationName) where TServiceContract : class
{
ChannelFactoryCacheKey cacheKey = new ChannelFactoryCacheKey(typeof(TServiceContract), endpointConfigurationName);
ChannelFactory<TServiceContract> channelFactory = (ChannelFactory<TServiceContract>)SvcHelper.ChannelFactories.GetOrAdd(
cacheKey,
missingCacheKey => new ChannelFactory<TServiceContract>(missingCacheKey.EndpointConfigurationName));
TServiceContract typedChannel = channelFactory.CreateChannel();
IClientChannel clientChannel = (IClientChannel)typedChannel;
try
{
using(new OperationContextScope((IContextChannel)typedChannel))
{
action(typedChannel);
}
}
finally
{
try
{
clientChannel.Close();
}
catch
{
clientChannel.Abort();
}
}
}
private sealed class ChannelFactoryCacheKey : IEquatable<ChannelFactoryCacheKey>
{
public ChannelFactoryCacheKey(Type channelType, string endpointConfigurationName)
{
this.channelType = channelType;
this.endpointConfigurationName = endpointConfigurationName;
}
private Type channelType;
public Type ChannelType
{
get
{
return this.channelType;
}
}
private string endpointConfigurationName;
public string EndpointConfigurationName
{
get
{
return this.endpointConfigurationName;
}
}
public bool Equals(ChannelFactoryCacheKey compareTo)
{
return object.ReferenceEquals(this, compareTo)
||
(compareTo != null
&&
this.channelType == compareTo.channelType
&&
this.endpointConfigurationName == compareTo.endpointConfigurationName);
}
public override bool Equals(object compareTo)
{
return this.Equals(compareTo as ChannelFactoryCacheKey);
}
public override int GetHashCode()
{
return this.channelType.GetHashCode() ^ this.endpointConfigurationName.GetHashCode();
}
}
}
This should work:
public class SvcHelper
{
public static void Using<TClient>(Action<TClient> action) where TClient : ICommunicationObject, IDisposable
{
ChannelFactory<TClient> cnFactory = new ChannelFactory<TClient>("SomethingWebService");
TClient client = cnFactory.CreateChannel();
using (new OperationContextScope((IContextChannel)client))
{
action(client);
}
}
}

Categories