how to execute code after deserializing a custom component? - c#

I am trying to implement a method that get's called on deserializing a custom component.
However, the methods marked as OnDeserializing and OnDeserialized are never called.
I found this question on SO and from the text I conclude that here these method's are being called. So I compared this code with mine.
Also in the documentation I cannot see anything that I am missing.
What I need is that when my custom component is deserializing from the Designer.cs on designtime, I can step in and do some extra coding.
So what am I missing here ?
[Serializable]
public partial class gttDataTable : Component, ISerializable
{
private Collection<ConfigColumn> _columns = new Collection<ConfigColumn>();
public gttDataTable()
{ }
public gttDataTable(SerializationInfo info, StreamingContext context)
{ }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<ConfigColumn> gttColumns
{
get { return _columns; }
set { _columns = value; }
}
[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context)
{
// this code is never called
throw new NotImplementedException();
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
// this code is never called
throw new NotImplementedException();
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// this code is never called
throw new NotImplementedException();
}
private IComponentChangeService GetChangeService()
{
return (IComponentChangeService)GetService(typeof(IComponentChangeService));
}
}
public class ConfigColumn
{
public string Name { get; set; }
public string Caption { get; set; }
public string ColumnName { get; set; }
public Type DataType { get; set; }
}
EDIT
For clarity, the problem is that both the internal methods are never called when the custom component is deseriazeling.
EDIT 2
I tried making the internal methods public, as suggested, but it makes no difference. They still are not called
EDIT 3
I read this link and doublechecked that all is the same as in the documetation. In my opinion it is all correct, but still the methods are not called

Not all serializer take into consideration such attribute as OnDeserializing etc. see e.g. Why does the OnDeserialization not fire for XML Deserialization?.
If I'm not mistaken designer does use CodeDomSerializer.
To make custom serailization you need to derive from CodeDomSerializer and decorate the class with DesignerSerializerAttribute
[DesignerSerializerAttribute(typeof(YourCustomSerializer), typeof(CodeDomSerializer))]
public partial class gttDataTable : Component
{
}

Related

How to provide some available values when using interface as type for form custom property?

If possible, I need to provide available implementations of an interface as values for a property of a custom form.
Below is a simple code example:
public interface IDoThings {
void DoInitialThing();
}
public class StandardDoer : IDoThings {
public void DoInitialThing() {
throw new Exception("I did something!");
}
}
public class NoDoer : IDoThings {
public void DoInitialThing() {
throw new Exception("I did nothing!");
}
}
public class AllDoer : IDoThings {
public void DoInitialThing() {
throw new Exception("I did everything!");
}
}
public partial class CustomForm : Form {
[Browsable(true)]
[Category("Behavior")]
[DefaultValue(null)]
[Description("The IDoThings override.")]
public IDoThings Doer { get; set; }
protected IDoThings _doerDefault = new StandardDoer();
public CustomForm() {
InitializeComponent();
(Doer ?? _doerDefault).DoInitialThing();
}
}
public partial class UsingCustomForm : CustomForm {
public UsingCustomForm() {
InitializeComponent();
}
}
Let's say we use reflection to gather all the types implementing "IDoThings" in a container (array, list, dictionary, ...) and let's say we are able to instantiate them using their name once one of them is chosen.
Question: Is it possible to make the "IDoThings" implementations known for the "UsingCustomForm"'s "Doer" property on design time in order to chose one (or none)?
I wouldn't want you to bother writing code. If the above is possible, please point me in the right direction. If not, maybe you have another approach? In any case I will try the recommendations and follow up if necessary.

How can an interface method be called directly?

I'm reading some code, can you please explain what the below line does?
bool isFeatureEnabled = FeatureControl.Current.Features.AppDesigner.IsEnabled(organizationId,currentOrgDBVersion);
Here's the definitions of the above code
public sealed class FeatureControl : IFeatureControl
{
public static IFeatureControl Current { get; }
[XmlIgnore]
public IFeatureDetailContainer Features { get; set; }
....
}
public interface IFeatureControl
{
IFeatureDetailContainer Features { get; set; }
...
}
public interface IFeatureDetailContainer
{
IFeatureDetail AppDesigner { get; }
}
public interface IFeatureDetail
{
bool IsEnabled(Guid organizationId, Version currentOrgDBVersion);
}
I don't see any instances created, how does this work?
Sorry, I copied metadata, I just found the actual code:
public sealed class FeatureControl : IFeatureControl
{
private static readonly Lazy<IFeatureControl> current = new Lazy<IFeatureControl>(() => new FeatureControl());
private IFeatureDetailContainer features;
public static IFeatureControl Current
{
get
{
return current.Value;
}
}
/// <summary>
/// Accessor to the Features List for Developers to retrieve the information
/// </summary>
[XmlIgnore]
public IFeatureDetailContainer Features
{
get
{
return this.features;
}
set
{
this.features = value;
}
}
}
It is a singleton pattern. Normally, the instance is created inside constructor.
public interface IFeatureControl { }
public sealed class FeatureControl : IFeatureControl
{
public static IFeatureControl Current { get; }
static FeatureControl()
{
if (Current == null)
{
Current = new FeatureControl();
}
}
}
[TestFixture]
public class FeatureControlTests
{
[Test]
public void IsFeatureControlSingleton()
{
IFeatureControl c1 = FeatureControl.Current;
IFeatureControl c2 = FeatureControl.Current;
Assert.AreSame(c1, c2);
}
}
At some point in the code (not shown here) you can expect the object IFeatureControl::Current is being created / new'd.
Your line of code is merely accessing that value. Note that if you run the code without actually instantiating the Current object you'll get a null ref. error.
You can program an elaborate set of code using Interfaces and the code will compile and look great, however if none of the interface objects are instantiated with new'd instances of classes that inherit from the Interface you'll get null reference exceptions.
Consider the use of interfaces in this example an outline for how things WILL be arranged and how they WILL operate. However it's just an outline and you'll need to colour inside the lines to actually achieve an outcome.
Good luck!

Exposing properties to an implementation of IList

I am having trouble with a piece of old code that I need to amend, I have added the Metadata property but cannot expose it, the code is simple.
public interface IBigThing : IList<ILittleThing>
{
string Metadata { get; set; }
}
[Serializable]
public class BigThing: List<ILittleThing>, IBigThing , ISerializable
{
string m_Metadata;
[DataMember]
public string Metadata
{
get { return m_Metadata; }
set { m_Metadata = value; }
}
#region Constructors
public BigThing()
{ }
public BigThing(string p_Metadata)
{
Metadata = p_Metadata;
}
#endregion
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Metadata", Metadata);
}
}
When I inspect the app or serialize to json, the Metadata is ignored and can only be accessed if explicitly called.
IBigThing toReturn = new BigThingFactory.Manufacture();
string strJson = new JavaScriptSerializer().Serialize(toReturn);
Im sure I am missing something simple, can anyone help please?
Add the [DataMember] attribute to the property definition in IBigThing. The serialization framework only analyses the types that you tell it about and therefore will not see any declarations in BigThing.

Getting warning, 'Type Parameter X Hides Interface X'

This is occurring in Visual Studio 2010.
I'm working with generic methods, and basically losing my intellisense and stopping me from continuing work on this project.
I basically have the following class:
public class SearchRepository : DataRepository<IAudit>
{
public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters)
{
// CODE GOES HERE
}
public override bool Delete<TIAudit>(IAudit audit)
{
// CODE GOES HERE
}
}
This inherits from:
public abstract class DataRepository<T>
{
public virtual IEnumerable<T> RetrieveAll<U>(U parameter1)
{
throw new NotImplementedException();
}
public virtual bool Delete<U>(U parameter1)
{
throw new NotImplementedException();
}
}
So Delete works exactly how I would expect it to work. I have intellisense and it compiles correctly. RetrieveAll doesn't work correctly using IAuditSearch. If I change it to TIAuditSearch, then it says I'm "There is no suitable method to override".
Not sure what I'm doing wrong, but it's definitely not happy with me.
UPDATED: changed the virtual to override for the Delete method at the top. That was a mistake.
You are implicitly hiding (by not overriding) the method signature of
bool Delete<myType>(myType param) { ... }
You can overcome the error my introducing the "new" keyword on the derived class's Delete property. This explicitly hides the signature and makes everyone happy as it illustrates your intent.
Read the Microsoft documentation at: http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx.
You can't define the method public override IEnumerable RetrieveAll(IAuditSearch searchParameters)
The method must still use the U type parameter in place of IAuditSearch. Its up to the caller to choose what type to pass.
You'll probably need to create an ISearch interface and on the base class add where U : ISearch, but even then your subclass would need to accept all ISearch implemenations, not just IAuditSearch.
Probably the best solution is to define an IAuditSearch repository which is what defines your RetreiveAll method.
EDIT: I see the question has changed. You now have the same problem on both methods; you cannot dictate which interface to use when overriding the method, you must maintain the generic type parameter.
public override IEnumerable<T> RetrieveAll<U>(U parameter1) { }
public override bool Delete<U>(U parameter1) { }
Note that you cannot add where clauses to the methods either; this breaks the Liskov Substitution Prinicple. Also I'm not even sure the compiler would allow you to do that.
Would the following code work instead?
public class SearchRepository : DataRepository<IAudit, IAuditSearch>
{
public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters)
{
// CODE GOES HERE
}
public override bool Delete<TIAudit>(IAudit audit)
{
// CODE GOES HERE
}
}
public abstract class DataRepository<T, TSearch>
{
public virtual IEnumerable<T> RetrieveAll(TSearch parameter1)
{
throw new NotImplementedException();
}
public virtual bool Delete(T parameter1)
{
throw new NotImplementedException();
}
}
So for every instantiation of DataRepository, we declare the result type (T), and the search type (TSearch).
-C
Unfortunately, the exact context is not quite clear to me, but I believe your code should look like this:
public interface IParameter<T> {
bool Match(T entry);
}
public abstract class DataRepository<T, TParameter>
where TParameter : IParameter<T> {
public abstract IEnumerable<T> RetrieveAll(TParameter parameter1);
public abstract bool Delete(TParameter parameter1);
}
//
public interface IAudit {/* ... */}
public interface IAuditSearch : IParameter<IAudit> {/* ... */}
public class SearchRepository : DataRepository<IAudit, IAuditSearch> {
public override bool Delete(IAuditSearch parameter1) {
// iterate by collection items using parameter matching
// CODE GOES HERE (DELETE ALL FOUND ENTRIES)
}
public override IEnumerable<IAudit> RetrieveAll(IAuditSearch parameter1) {
// iterate by collection items using parameter matching
// CODE GOES HERE (RETURN ALL FOUND ENTRIES)
}
}
Different IAuditSearch implementation will incapsulate a "search by different parameter" logic:
var guidSearchResult = repository.RetrieveAll(
new GuidSearch(new Guid("00000000-0000-0000-0000-000000000000")));
var idRangeSearchResult = repository.RetrieveAll(
new IDRangeSearch(1000, 2000));
where GuidSearch and IDRangeSearch are implemented as:
public class GuidSearch : IAuditSearch {
Guid ID;
public GuidSearch(Guid id) {
this.ID = id;
}
public bool Match(IAudit entry) {
/* search implementation using ID(Guid)*/
throw new NotImplementedException();
}
}
public class IDRangeSearch : IAuditSearch {
int StartID;
int EndID;
public IDRangeSearch(int startId, int endId) {
this.StartID = startId;
this.EndID = endId;
}
public bool Match(IAudit entry) {
/* search implementation using ID range (StartID...EndID)*/
throw new NotImplementedException();
}
}

How to restrict access to nested class member to enclosing class?

Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?
Here's an illustration of the problem (of course my actual code is a bit more complex...) :
public class Journal
{
public class JournalEntry
{
public JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
// ...
}
I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !
Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.
Any suggestion would be appreciated !
UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)
Actually there is a complete and simple solution to this problem that doesn't involve modifying the client code or creating an interface.
This solution is actually faster than the interface-based solution for most cases, and easier to code.
public class Journal
{
private static Func<object, JournalEntry> _newJournalEntry;
public class JournalEntry
{
static JournalEntry()
{
_newJournalEntry = value => new JournalEntry(value);
}
private JournalEntry(object value)
{
...
If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.
public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}
If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.
If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:
typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });
Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class
public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
static Journal()
{
JournalEntry.Initialize();
}
static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}
This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces
Make JournalEntry a private nested type. Any public members will be visible only to the enclosing type.
public class Journal
{
private class JournalEntry
{
}
}
If you need to make JournalEntry objects available to other classes, expose them via a public interface:
public interface IJournalEntry
{
}
public class Journal
{
public IEnumerable<IJournalEntry> Entries
{
get { ... }
}
private class JournalEntry : IJournalEntry
{
}
}
A simpler approach is to just use an internal constructor, but make the caller prove who they are by supplying a reference that only the legitimate caller could know (we don't need to be concerned about non-public reflection, because if the caller has access to non-public reflection then we've already lost the fight - they can access a private constructor directly); for example:
class Outer {
// don't pass this reference outside of Outer
private static readonly object token = new object();
public sealed class Inner {
// .ctor demands proof of who the caller is
internal Inner(object token) {
if (token != Outer.token) {
throw new InvalidOperationException(
"Seriously, don't do that! Or I'll tell!");
}
// ...
}
}
// the outer-class is allowed to create instances...
private static Inner Create() {
return new Inner(token);
}
}
In this case you could either:
Make the constructor internal - this stops those outside this assembly creating new instances or...
Refactor the JournalEntry class to use a public interface and make the actual JournalEntry class private or internal. The interface can then be exposed for collections while the actual implementation is hidden.
I mentioned internal as a valid modifier above however depending on your requirements, private may be the better suited alternative.
Edit: Sorry I mentioned private constructor but you've already dealt with this point in your question. My apologies for not reading it correctly!
For generic nested class =)
I know this is an old question and it has already an accepted answer, nevertheless for those google swimmers who may have a similar scenario to mine this answer may provide some help.
I came across this question for I needed to implement the same feature as the OP. For my first scenario this and this answers worked just fine. Nevertheless I needed also to expose a nested generic class. The problem is that you can not expose a delegate type field (the factory field) with opened generic parameters without making your own class generic, but obviously this is not what we want, so, here is my solution for such scenario:
public class Foo
{
private static readonly Dictionary<Type, dynamic> _factories = new Dictionary<Type, dynamic>();
private static void AddFactory<T>(Func<Boo<T>> factory)
=> _factories[typeof(T)] = factory;
public void TestMeDude<T>()
{
if (!_factories.TryGetValue(typeof(T), out var factory))
{
Console.WriteLine("Creating factory");
RuntimeHelpers.RunClassConstructor(typeof(Boo<T>).TypeHandle);
factory = _factories[typeof(T)];
}
else
{
Console.WriteLine("Factory previously created");
}
var boo = (Boo<T>)factory();
boo.ToBeSure();
}
public class Boo<T>
{
static Boo() => AddFactory(() => new Boo<T>());
private Boo() { }
public void ToBeSure() => Console.WriteLine(typeof(T).Name);
}
}
We have Boo as our internal nested class with a private constructor and we mantain on our parent class a dictionary with these generic factories taking advantage of dynamic. So, each time TestMeDude is called, Foo searches for whether the factory for T has already been created, if not it creates it calling nested class' static constructor.
Testing:
private static void Main()
{
var foo = new Foo();
foo.TestMeDude<string>();
foo.TestMeDude<int>();
foo.TestMeDude<Foo>();
foo.TestMeDude<string>();
Console.ReadLine();
}
The output is:
The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.
I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.
public class AllowedToEmailFunc
{
private static Func<long, EmailPermit> CreatePermit;
public class EmailPermit
{
public static void AllowIssuingPermits()
{
IssuegPermit = (long userId) =>
{
return new EmailPermit(userId);
};
}
public readonly long UserId;
private EmailPermit(long userId)
{
UserId = userId;
}
}
static AllowedToEmailFunc()
{
EmailPermit.AllowIssuingPermits();
}
public static bool AllowedToEmail(UserAndConf user)
{
var canEmail = true; /// code checking if we can email the user
if (canEmail)
{
return IssuegPermit(user.UserId);
}
else
{
return null
}
}
}
This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .

Categories

Resources