Object obtained from WCF service has null private fields, even though they are initialized in the class [duplicate] - wcf

I need to initialize private readonly field after Deserialization. I have folowing DataContract:
[DataContract]
public class Item
{
public Item()
{
// Constructor not called at Deserialization
// because of FormatterServices.GetUninitializedObject is used
// so field will not be initialized by constructor at Deserialization
_privateReadonlyField = new object();
}
// Initialization will not be called at Deserialization (same reason as for constructor)
private readonly object _privateReadonlyField = new object();
[DataMember]
public string SomeSerializableProperty { get; set; }
[OnDeserializing]
public void OnDeserializing(StreamingContext context)
{
// With this line code even not compiles, since readonly fields can be initialized only in constructor
_privateReadonlyField = new object();
}
}
All what I need, that after Deserialization _privateReadonlyField is not null.
Any suggestions about this - is it possible at all?
Or I need to remove "readonly" key, which is not a good option.

Serialization is able to read in values for read-only fields because it uses reflection, which ignores accessibility rules. It can be argued that the following is, therefore, justified as part of the serialization process, even though I would recommend strongly against it in almost any other circumstance:
private readonly Doodad _oldField;
[OptionalField(VersionAdded = 2)]
private readonly Widget _newField;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
if (_oldField != null && _newField == null)
{
var field = GetType().GetField("_newField",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly |
System.Reflection.BindingFlags.NonPublic);
field.SetValue(this, new Widget(_oldField));
}
}

Any field declared as private readonly can be instantiated in the same line where it was declared or inside a constructor. Once that is done it cannot be changed.
From MSDN:
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
That means that you will have to remove readonly keyword to get it to work.

Related

Jackson fails with "Cannot construct instance of WorkpoolId (although at least one Creator exists): no int/Int-argument constructor/factory"

I have the following class
public class WorkpoolId implements Serializable {
#NotNull
private Long id = null;
#JsonCreator
public WorkpoolId(#JsonProperty("workpoolId") long id) {
this.id = Long.valueOf(id);
}
public WorkpoolId(Long id) {
this.id = id;
}
public WorkpoolId(String id) {
this.id = Long.valueOf(id);
}
private WorkpoolId() {
}
}
when mapping
"workpoolId":1
to this class I get a
javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of WorkpoolId (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
Why is jackson not able to use the long constructor for the number value?
It fails because your WorkpoolId does not have access to field workpoolId it is not in its context anuymore. When your JSON is deserialized it could be deserialized either as an
independent object (having no field workpoolId, it IS the workbookId)
field object value in an object containing -say Data - it that might be named as workpoolId.
Now the use of workbookId could be usable for the JsonCreator in Data when constructing its field workpoolId.
To clarify this a bit, here is an example of possible Data class:
#Getter #Setter
public class Data {
private WorkpoolId workpoolId;
#JsonCreator // here it is a property!
public Data(#JsonProperty("workpoolId") long id) {
this.workpoolId = new WorkpoolId(id);
}
}
Json would be like {"workpoolId":1}
To have it work just remove the annotation #JsonProperty("workpoolId") from the attribute declaration. Actually the whole #JsonCreator annotation is not needed.

Is there a possibility to control the Expando class to not allow adding properties/members under certain conditions?

As far as I can tell, the Expando class in Kephas allows adding new members on the fly. Unlike the ExpandoObject in .NET, I noticed it is not sealed, so I could change its behavior, but I don't really know how.
[EDITED]
My scenario is to make the expando readonly at a certain time.
Try this snippet:
public class ReadOnlyExpando : Expando
{
private bool isReadOnly;
public ReadOnlyExpando()
{
}
public ReadOnlyExpando(IDictionary<string, object> dictionary)
: base(dictionary)
{
}
public void MakeReadOnly()
{
this.isReadOnly = true;
}
protected override bool TrySetValue(string key, object value)
{
if (this.isReadOnly)
{
throw new InvalidOperationException("This object is read only").
}
return base.TrySetValue(key, value);
}
}
For other scenarios you may want to check the LazyExpando class, which provides a way to resolve dynamic values based on a function, also handling circular references exception.

How to define protected field with public accessor in Kotlin

I have the following situation:
data class Person(val name: string=""):Entity { }
open class Entity() { var id: Long=0 }
In this way, id is a public property, and the associated field is private (is not visible in Person class).
I'm working on an annotation processor and the annotation that I've defined works on fields. How can I define the property id as protected field with public accessor?
You can set as a public variable and work with the scope of its setter, in this case, set the setter as protected using:
var yourField: Any = /** initial value **/
protected set
Read more about Visibility modifiers here

Object reference not set to an instance of an object, Interface

I know that this is one of the most encountered error but I am really struggling to get around it.
i have a property on my Controller:
private readonly ISelectListFactory _selectFactory;
and a method that called to populate the viewbag
private void PopulateLists()
{
var continent = _selectFactory.GetItems();
}
and the interface
public interface ISelectListFactory
{
IEnumerable<SelectListItem> GetItems();
}
and in the controller constructor I have the following:
public LocationController(ISelectListFactory selectFactory)
{
_selectFactory = selectFactory;
}
but I am getting this error Object reference not set to an instance of an object and not sure how to overcome it.
Regards
Make sure you have instantiated this _selectFactory variable somewhere. Like for example:
_selectFactory = new SomeConcreteSelectListFactory();
or if you are using dependency injection you might configure your DI framework to inject it into the constructor:
public class HomeController: Controller
{
private readonly ISelectListFactory _selectFactory;
public HomeController(ISelectListFactory selectFactory)
{
_selectFactory = selectFactory;
}
... some controller actions where you could use the _selectFactory field
}

Ninject Cascading Inection with IList

I am trying to use Ninject to implement cascading injection into a class that contains an IList field. It seems that, unless I specifically specify each binding to use in the kernel.Get method, the IList property is always injected with a list of a single default object.
The following VSTest code illustrates the problem. The first test fails because the IList field contains one MyType object with Name=null. The second test passes, but I had to specifically tell Ninject what constructor arguments to use. I am using the latest build from the ninject.web.mvc project for MVC 3.
Does Ninject specifically treat IList different, or is there a better way to handle this? Note that this seems to only be a problem when using an IList. Createing a custom collection object that wraps IList works as expected in the first test.
[TestClass()]
public class NinjectTest
{
[TestMethod()]
public void ListTest_Fails_NameNullAndCountIncorrect()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>();
var actual = target.GetList();
// Fails. Returned value is set to a list of a single object equal to default(MyType)
Assert.AreEqual(2, actual.Count());
// Fails because MyType object is initialized with a null "Name" property
Assert.AreEqual("Fred", actual.First().Name);
}
[TestMethod()]
public void ListTest_Passes_SeemsLikeUnnecessaryConfiguration()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>(new ConstructorArgument("myGenericObject", kernel.Get<IGenericObject<MyType>>(new ConstructorArgument("myList", kernel.Get<IList<MyType>>()))));
var actual = target.GetList();
Assert.AreEqual(2, actual.Count());
Assert.AreEqual("Fred", actual.First().Name);
}
}
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IList<MyType>>().ToConstant(new List<MyType> { new MyType { Name = "Fred" }, new MyType { Name = "Bob" } });
Bind<IGenericObject<MyType>>().To<StubObject<MyType>>();
}
}
public class MyModel
{
private IGenericObject<MyType> myGenericObject;
public MyModel(IGenericObject<MyType> myGenericObject)
{
this.myGenericObject = myGenericObject;
}
public IEnumerable<MyType> GetList()
{
return myGenericObject.GetList();
}
}
public interface IGenericObject<T>
{
IList<T> GetList();
}
public class StubObject<T> : IGenericObject<T>
{
private IList<T> _myList;
public StubObject(IList<T> myList)
{
_myList = myList;
}
public IList<T> GetList()
{
return _myList;
}
}
public class MyType
{
public String Name { get; set; }
}
lists, collections and arrays are handled slightly different. For those types ninject will inject a list or array containing an instance of all bindings for the generic type. In your case the implementation type is a class which is aoutobound by default. So the list will contain one instance of that class. If you add an interface to that class and use this one the list will be empty.