Additional data in UITypeEditor EditValue - c#

I have some problems accessing contextual data in a custom UITypeEditor. I'm using a PropertyGrid to display some settings using Windows Forms. The SelectedObject of the PropertyGrid contains a List<A>. Type A has a property for which I have created a custom editor that needs some external information to be able to customize it for different instances of PropertyGrid.
I've attempted the approach of using the IServiceProvider passed to EditValue to access a custom service that contains the data. It was suggested by ironic in an answer here Passing objects to a UITypeEditor but I haven't managed to get it to work. GetService always returns null inside EditValue. I think my problem is that the ISite I set as PropertyGrid.Site isn't reachable in the nested UITypeEditor where the information is needed (when I attempt to get the service using GetService inside the list's editor's EditValue method it works).
Does anyone know how to make my ISite propagate to nested UITypeEditors?
Some pseudo code:
public interface IMyService {
object GetUserData();
}
public class MyService : IMyService {
private object userData;
public MyService(object ud) {
userData = ud;
}
public object GetUserData() {
return userData ;
}
}
public class MySite : ISite {
private object userData;
public MySite(object ud) {
userData = o;
}
...
public object GetService(Type serviceType) {
if (serviceType == typeof(IMyService))
{
return (IMyService) new MyService(userData);
}
else
{
return null;
}
}
}
public class A {
[Editor(typeof(EditorA), typeof(UITypeEditor)]
public object SomeEditedProperty { ... }
}
public EditorA : UITypeEditor {
...
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
...
public override object EditValue(ITypeDescriptorContext c, IServiceProvider p, object v) {
// This always returns null!
object myService = p.GetService(typeof(IMyService));
...
object myData = myService.GetUserData();
...
}
}
public class EditedObject {
[Editor(...)]
public List<A> Stuff { ... }
}
// somewhere
object userData = new object();
propertyGrid.Site = new MySite(userData);
EditedObject objectToEdit = new EditedObject();
...
propertyGrid.SelectedObject = objectToEdit;

Related

C# Ninject not injecting on deserialize from JSON

I'm writing a simple windows service, and I want to use a Dependency Injection.
On service start, the app read the JSON string from file, and deserialize it to object.
One of property in JSON is list of 'Bar' objects, and in 'Bar' constructor I want to inject FooService.
I suspected that following code will works, but 'service' in 'Bar' constructor is null.
Can anyone expalin me, why this code not working, and how to change it to works?
That's my code:
NinjectBinding.cs
class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<IFooService>().To<FooService>();
Bind<Bar>().ToSelf().WithConstructorArgument("service", ctx => ctx.Kernel.Get<IFooService>());
}
}
Deserializator.cs
internal class Deserializator
{
internal static void GetFilePaths()
{
var json = JsonConvert.DeserializeObject<Deserializator>("{}");///... Read from JSON File
}
public List<Bar> BarList { get; set; }
}
Bar.cs
public class Bar {
private readonly IFooService _fooService;
public Bar (IFooService service){
// here service is null
using (var kernel = new StandardKernel(new NinjectBindings())){
var kernelService = kernel.Get<IFooService>();
// here kernelService is NOT null
}
}
}
UPDATE
I found solution on https://www.newtonsoft.com/json/help/html/DeserializeWithDependencyInjection.htm
I've added NinjectResolver.cs
class NinjectResolver : DefaultContractResolver
{
private readonly IKernel _container;
public NinjectResolver(IKernel container)
{
_container = container;
}
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
if (_container.TryGet(objectType) != null)
{
JsonObjectContract contract = ResolveContact(objectType);
contract.DefaultCreator = () => _container.Get(objectType);
return contract;
}
return base.CreateObjectContract(objectType);
}
private JsonObjectContract ResolveContact(Type objectType)
{
return base.CreateObjectContract(objectType);
}
}
remove Bind from NinjectBindings, and change SerializationMethod to:
var json = JsonConvert.DeserializeObject<Deserializator>("{}", new
JsonSerializerSettings()
{
ContractResolver = new NinjectResolver(new StandardKernel(new NinjectBindings()))
});
And now - it works.

How can I test methods containing Application.Current

There are few methods which have Application.Current.Properties and Application.Current.SavePropertiesAsync methods.
So how do I test methods having these two in them? I'm stuck after trying to use Unity container for them but its only working for Properties not SavePropertiesAsync.
How can I implement it?
I have implemented it as:
public interface IAppProperties { IDictionary<string, object> Properties { get; set; } }
public class AppProperty:IAppProperties
{
public const string AppPropertiesName = "AppProperties";
public IDictionary<string, object> Properties { get; set; }
public AppProperty(IDictionary<string, object> appProperties)
{
Properties = appProperties;
}
}
In App XAML.cs
UnityContainer container = new UnityContainer();
if (!IsUnitTestCase)
{
container.RegisterInstance<IDictionary<string, object>>(AppProperty.AppPropertiesName, Application.Current.Properties);
}
else
{
container.RegisterInstance<IDictionary<string, object>>(AppProperty.AppPropertiesName, new Dictionary<string,object>());
}
container.RegisterType<IAppProperties,AppProperty>();
Application.Current.Resources.Add("Unity", container);
If a class depends directly on Application.Current then you can't test it. But it looks like you're already on track with depending on an abstraction.
Suppose there are three things you need to be able to do:
Retrieve a property
Set a property
Save all properties
You can define an abstraction that represents those behaviors:
public interface IApplicationProperties
{
object GetProperty(string key);
void SetProperty(string key, object value);
Task SavePropertiesAsync();
}
Your default implementation could look like this (although there's plenty of room for improvement.)
public class ApplicationProperties : IApplicationProperties
{
private readonly Application _application;
public ApplicationProperties(Application application)
{
_application = application;
}
public object GetProperty(string key)
{
// or whatever behavior you want when the key is missing
return _application.Properties.TryGetValue(key, out object result) ? result : null;
}
public void SetProperty(string key, object value)
{
_application.Properties[key] = value;
}
public async Task SavePropertiesAsync()
{
await _application.SavePropertiesAsync();
}
}
This class could either depend on Application.Current or you could inject the Application into it.
This could benefit from better type checking and perhaps limiting/defining what settings can be read and set. But it allows you to both access the behaviors of Application through an abstraction while mocking the abstraction for unit tests. You could use Moq or just write a simple test double to use in tests.
Here's a tweak to the approach that includes a test double:
// base class
public abstract class ApplicationPropertiesBase : IApplicationProperties
{
protected abstract IDictionary<string, object> Properties { get; }
public object GetProperty(string key)
{
return Properties.TryGetValue(key, out object result) ? result : null;
}
public void SetProperty(string key, object value)
{
Properties[key] = value;
}
public abstract Task SavePropertiesAsync();
}
// inject this
public class ApplicationProperties : ApplicationPropertiesBase
{
private readonly Application _application;
public ApplicationProperties(Application application)
{
_application = application;
}
protected override IDictionary<string, object> Properties => _application.Properties;
public override async Task SavePropertiesAsync()
{
await _application.SavePropertiesAsync();
}
}
// use for tests
public class ApplicationPropertiesTestDouble : ApplicationPropertiesBase
{
private readonly IDictionary<string, object> properties =
new Dictionary<string, object>();
protected override IDictionary<string, object> Properties => properties;
public override async Task SavePropertiesAsync()
{ }
}

Injecting object into WCF pipeline, doing work before and after every OperationContract call

I'm looking for a way to keep track of the total time spent on the database, and merge it over one Service Operation call or maybe even an entire session. Since I'm currently using the default PerCall InstanceContextMode, the constructor of the Service class is called every time a service method is called, so I was thinking something like hooking into some pipeline method that is called before and after each service method, calling a non-empty constructor. And then injecting an object to pass further into the hierarchy:
[ServiceContract]
public interface IJobsService { ... }
public partial class JobsService : IJobsService
{
public PerformanceContext PerformanceContext { get; private set; }
JobsService() { ... }
JobsService(PerformanceContext context) : this()
{
RequestContext = context;
}
}
public class PerformanceContext
{
private object syncObj = new object();
private long? userID;
public long? UserID { ... }
public string Source { get; set; }
private long totalTicksUsed = 0;
public long TotalTicksUsed
{
get { return totalTicksUsed; }
private set { totalTicksUsed = value; }
}
public void AddTicksUsed(long ticks, long? userID)
{
Interlocked.Add(ref totalTicksUsed, ticks);
UserID = userID;
}
}
Then I would have the reference of it outside the scope of the service contract, and be able to log it there.
As it is now, the "simplest" way for me to implement this behavior is to call a logging function in the very end of every single service method, but I don't find it very pretty, if there's a better way.
I've tried following Explicitly calling a service constructor when hosting a WCF web service on IIS, Hooking into wcf pipeline and some of the Carlos Figueira MSDN blog: WCF Extensibility, without much success. I'm also having trouble finding much documentation on it general. In other words, I'm stuck.
I am a bit torn between the IOperationInvoker and the IInstanceProvider.
The IOperationInvoker has turned out to be fairly complicated for what I need, since I need to extend both synchronous and asynchronous calls. But it's advantage is that it is specifically made to perform actions before and after each method call. Although I'm still not entirely sure how to pass on an object to any service method, which I can use to track the use, lower in the hierarchy. And Carlos Figueira's blog on WCF Extensibility unfortunately doesn't touch on this in his example (he shows how to cache calls).
The IInstanceProvider turned out to be more simple for me to implement, and also makes it possible to perform actions before and after each operation - as long as the InstanceContextMode is PerCall. If I were to change it to PerSession, I would suddenly perform the actions once per session instead. But in my case, that's acceptable, since the primary objective is to merge the data as much as possible:
One of my Service classes with the custom ServiceBehavior Attribute and inheriting an abstract type that dictates we have a constructor that takes a PerformanceContext:
[ServiceContract]
public interface IJobsService { ... }
[PerformanceInstanceProviderBehavior]
public partial class JobsService : PerformanceMonitoredService, IJobsService
{
public PerformanceContext PerformanceContext { get; protected set; }
JobsService() { ... }
JobsService(PerformanceContext perfContext) : this()
{
PerformanceContext = perfContext;
}
...
}
IInstanceProvider which allows calling a specific constructor and injecting an IExtension into the pipeline, which we can obtain after the Service instance is released:
public class ServiceInstanceProvider : IInstanceProvider
{
public Type ServiceType { get; set; }
public ServiceInstanceProvider(Type serviceType) { ServiceType = serviceType; }
public object GetInstance(InstanceContext instanceContext)
{
return this.GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
var perfContext = new PerformanceInstanceContext();
instanceContext.Extensions.Add(new PerformanceInstanceExtension(perfContext));
return ServiceFactory.Create(ServiceType, perfContext);
//return new JobsService(perfContext);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
var perfContext = (instanceContext.Extensions.FirstOrDefault(ice =>
ice is PerformanceInstanceExtension)
as PerformanceInstanceExtension
)?.PerformanceContext;
//Handle the object which has been through the pipeline
//Note (IErrorHandler):
//This is called after "ProvideFault", but before "HandleError"
}
}
The IServiceBehavior and Attribute that will be added to all services that needs a PerformanceContext injected.
public class PerformanceInstanceProviderBehaviorAttribute : Attribute, IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
if (!ed.IsSystemEndpoint)
{
//Each Service Type is getting their own InstanceProvider,
//So we can pass the type along,
//and let a factory create the appropriate instances:
ed.DispatchRuntime.InstanceProvider =
new ServiceInstanceProvider(serviceDescription.ServiceType);
}
}
}
}
...
}
The IExtension that we can attach to the InstanceContext through the instance provider pipeline:
public class PerformanceInstanceExtension : IExtension<InstanceContext>
{
public PerformanceInstanceExtension()
{
PerformanceContext = new PerformanceContext();
}
public PerformanceInstanceExtension(PerformanceContext perfContext)
{
PerformanceContext = perfContext;
}
public PerformanceContext PerformanceContext { get; private set; }
public void Attach(InstanceContext owner) {}
public void Detach(InstanceContext owner) {}
}
The abstract service type that should allow this injection:
public abstract class PerformanceMonitoredService
{
public abstract PerformanceContext PerformanceContext { get; protected set; }
public PerformanceMonitoredService() {}
public PerformanceMonitoredService(PerformanceContext perfContext) {}
}
A factory for services that inherit PerformanceMonitoredService:
public class PerformanceServiceFactory
{
private static ConcurrentDictionary<Type, ConstructorInfo> Constructors
= new ConcurrentDictionary<Type, ConstructorInfo>();
public static object Create(Type type, PerformanceContext perfContext)
{
ConstructorInfo ctor;
if(Constructors.TryGetValue(type, out ctor))
{
return InvokeConstructor(ctor, perfContext);
}
else if (type.IsSubclassOf(typeof(PerformanceMonitoredService))
||type.IsAssignableFrom(typeof(PerformanceMonitoredService)))
{
ConstructorInfo newCtor = type.GetConstructor(
new[] { typeof(PerformanceContext) }
);
if(Constructors.TryAdd(type, newCtor))
{
return InvokeConstructor(newCtor, perfContext);
} else if(Constructors.TryGetValue(type, out ctor))
{
return InvokeConstructor(ctor, perfContext);
}
}
throw new ArgumentException(
$"Expected type inheritable of {typeof(PerformanceMonitoredService).Name}"}",
"type");
}
private static object InvokeConstructor(ConstructorInfo ctor,
PerformanceContext perfContext)
{
return ctor.Invoke(new object[] { perfContext });
}
}

Inheriting an already instantiated base object

Is it possible to do something like the following:
public class ChildClass : BaseClass
{
public ChildClass(BaseClass o)
{
base = o;
}
}
Basically, I want a transparent way to wrap a base class inside of other functionality. One example I've thought of is a custom Settings Provider which transparently audits the settings passed through it.
public class SettingsAuditor : SettingsProvider
{
public SettingsAuditor(SettingsProvider o)
{
base = o;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
base.SetPropertyValues(context, propvals);
}
}
Then I could do the following:
mySettingsProvider = new SettingsAuditor(mySettingsProvider);
And all changes would go through the overridden SetPropertyValues before passing to the original object.
I could use a private SettingsProvider member, but then I either cannot inherit from SettingsProvider, or have an entire SettingsProvider (base) not being used at all.
I'm using C# 4.0 and .Net 4.0.
You cannot do base = o;
What you're looking for is the Decorator Pattern), which is a way to compositionally add functionality at runtime (vs. inheritance).
Instead of trying to set the base, you just contain the inner member. As long as the wrapper implements the same interface or base class as the inner object, you can pass back the new wrapper. You can wrap as many decorators as you want.
Consider:
public interface ICar
{
void Drive();
}
public class Car : ICar
{
public void Drive()
{
Console.WriteLine("vroom");
}
}
public class BuckleUp : ICar
{
ICar car;
public BuckleUp(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("click!");
car.Drive();
}
}
public class CheckMirrors : ICar
{
ICar car;
public CheckMirrors(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("mirrors adjusted");
car.Drive();
}
}
Now consider you have a method that accepts an ICar and tells it to drive. You could give it a Car, and it would work, but you could also wrap that car in a BuckleUp and a CheckMirrors and you wouldn't have to change that method at all. You've modified functionality through composition using the Decorator Pattern.
No. This looks like it should be a Composition vs Inheritance issue. You need to evaluate whether you are a "is a" or a "has a."
A little help for your journey
This is not a complete implmentation and it could probably be done much cleaner with expression trees... but this was a quick swing at faking AOP using DynamicObject with .Net 4.0.
public class MyDynamicWrapper<T> : DynamicObject
{
public T Wrapped { get; private set; }
public Action<T> Pre { get; private set; }
public Action<T> Post { get; private set; }
public MyDynamicWrapper(T wrapped, Action<T> pre, Action<T> post)
{
this.Wrapped = wrapped;
this.Pre = pre;
this.Post = post;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
var type = typeof(T);
var method = type.GetMethod(binder.Name);
if (method != null)
{
Func<object> func = () =>
{
if (Pre != null)
Pre(Wrapped);
// support for input parameters could be added here
var ret = method.Invoke(Wrapped, null);
if (Post != null)
Post(Wrapped);
return ret;
};
result = func;
return true;
}
return base.TryGetMember(binder, out result);
}
}
public class MyDynamicWrapper
{
public static MyDynamicWrapper<T> Create<T>(
T toWrap,
Action<T> pre = null,
Action<T> post = null)
{
return new MyDynamicWrapper<T>(toWrap, pre, post);
}
}
public class MyObject
{
public void MyMethod()
{
Console.WriteLine("Do Something");
}
}
class Program
{
static void Main()
{
var myobject = new MyObject();
dynamic mydyn = MyDynamicWrapper.Create(
myobject,
p => Console.WriteLine("before"),
p => Console.WriteLine("after"));
// Note that you have no intellisence...
// but you could use the old implmentation before you
// changed to this wrapped version.
mydyn.MyMethod();
/* output below
before
Do Something
after
*/
}
}
No, but you could fake it:
public class SettingsAuditor
{
SettingsProvider #base;
public SettingsAuditor(SettingsProvider o)
{
#base = o;
}
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
#base.SetPropertyValues(context, propvals);
}
}
Note here, #base isn't the actual base, just a varaible named base

Custom lifetime management in DI containers (wcf proxy: Unity vs Castle Windsor)

I've found nice post: Singleton WCF Proxy.
It is about the implementation of WCF proxy life scope using Castle Windsor DI container.
Implementation of the abstract class AbstractLifestyleManager from Castle.MicroKernel.Lifestyle namespace overrides 3 methods: Resolve, Dispose and Release. In the Release method we have access to the context, from which we can resolve service instance.
I've copied the code from that post (with a small change) below:
public class SingletonWCFProxyLifestyleManager : AbstractLifestyleManager
{
private object instance;
public override object Resolve(Castle.MicroKernel.CreationContext context)
{
lock (base.ComponentActivator)
{
if (this.instance == null)
{
this.instance = base.Resolve(context);
}
else
{
ICommunicationObject communicationObject = this.instance as ICommunicationObject;
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch { }
this.instance = base.Resolve(context);
}
}
}
return this.instance;
}
public override void Dispose()
{
if (this.instance != null)
{
base.Release(this.instance);
}
}
public override void Release(object instance)
{
}
}
I would like to provide the same functionality using Unity container. It looks like the LifetimeManager class from Microsoft.Practices.Unity namespace (and optionally IRequiresRecovery interface) is dedicated for that.
All methods that class is providing are shown below:
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery
{
public override object GetValue()
{
throw new NotImplementedException();
}
public override void RemoveValue()
{
throw new NotImplementedException();
}
public override void SetValue(object newValue)
{
throw new NotImplementedException();
}
#region IRequiresRecovery Members
public void Recover()
{
throw new NotImplementedException();
}
#endregion
}
And here is the question:
How to provide the same functionality in the second example (using Unity), as it was done in the first example (using Castle Windsor) ?
(PS: There is no access to the context of the container, so how I can resolve the object ?).
Regards
I'll try to answer my question (I hope that correctly..).
I've found this post Writing Custom Lifetime Managers. I've been trying to implement solution I've described previously in details, based on that post and the previous one: Singleton WCF Proxy.
Below is what I have created. Of course I have to test that code. For the first look, it is rather ok, but I'll see later.
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery, IDisposable
{
private static readonly object _locker = new object();
private Guid _key;
public SingletonWCFProxyLifestyleManager()
{
_key = Guid.NewGuid();
}
public override object GetValue()
{
Monitor.Enter(_locker);
object result = Storage.Instance.Get(_key);
if (result != null)
{
ICommunicationObject communicationObject = result
as ICommunicationObject;
//If the proxy is in faulted state, it's aborted and a new proxy is created
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch
{
}
Dispose();
return null; //Return before releasing monitor
}
Monitor.Exit(_locker);
}
return result;
}
public override void RemoveValue()
{
}
public override void SetValue(object newValue)
{
Storage.Instance.Set(_key, newValue);
TryToReleaseMonitor();
}
#region IRequiresRecovery Members
public void Recover()
{
TryToReleaseMonitor();
}
#endregion
private void TryToReleaseMonitor()
{
try
{
Monitor.Exit(_locker);
}
catch(SynchronizationLockException)
{
} // This is ok, just means we don't hold the lock
}
#region IDisposable Members
public void Dispose()
{
object result = Storage.Instance.Get(_key);
if (result != null)
{
try
{
Storage.Instance.RemoveAndDispose(_key);
}
catch
{
ICommunicationObject communicationObject = result as ICommunicationObject;
if (communicationObject != null)
{
communicationObject.Abort();
}
}
}
}
#endregion
}
Storage utility class has been created for caching instances of services (it contains hashtable ans a few utility methods, like Get or RemoveAndDispose), but it is too simple for pasting it here.

Categories

Resources