Weird Unity issue - base and class interface type map to same class but gives wrong resolve result when reference the base interface - unity-container

I defined 2 types, a base interface and child interface inherited from base. Both type map to the same implementation class in the Unity configuration. In a container class whose property defined as base interface. Finally after Unity resolves my container class, I found the value of resolved property is from a child interface instead of the base interface I configured in there. Below is the code and Unity configuration. I know I can use name to differentiate it but try to understand how unity treat this scenario.
Code:
IBaseInterface defines a property string BaseString.
public interface IBaseInterface
{
string BaseString { set; get; }
}
IChildInterface inherited from IBaseInterface and defines a property string ChildString
public interface IChildInterface : IBaseInterface
{
string ChildString { set; get; }
}
ChildClass implements IChildInterface defines 2 properties, BaseString and ChildString
public class ChildClass : IChildInterface
{
public string BaseString { set; get; }
public string ChildString { set; get; }
}
ContainerClass contains a property impl whose type is IBaseInterface
public class ContainerClass
{
public IBaseInterface impl { set; get; }
}
Unity Configuration:
Register type IBaseInterface maps to ChildClass with 2 properties whose value are started with IBaseInterface
<register type="IBaseInterface" mapTo="TestUnity.ChildClass, TestUnity">
<lifetime type="transient"/>
<property name="BaseString" value="IBaseInterface_BaseString" />
<property name="ChildString" value="IBaseInterface_ChildString" />
</register>
Register type IChildInterface maps to the same type, ChildClass with 2 properties whose value are started with IChildInterface
<register type="IChildInterface" mapTo="TestUnity.ChildClass, TestUnity">
<lifetime type="transient" />
<property name="BaseString" value="IChildInterface_BaseString" />
<property name="ChildString" value="IChildInterface_ChildString" />
</register>
Register type ContainerClass with name Test and mapto Container class. It has one property impl whose dependencType is IBaseInterface.
<register name="Test" type="TestUnity.ContainerClass, TestUnity" mapTo="TestUnity.ContainerClass, TestUnity">
<lifetime type="transient" />
<property name="impl" dependencyType="IBaseInterface" />
</register>
After the program run, the instance of ContainerClass resolved has property impl and the string values of its properties are started with IChildInterface which is from the type IChildInterface.

Related

How to set property calue of bean as a value getting returned from method of another class?

I am working on one of the task in Hybris where i need to fetch the value of attribute from one class "a" to class "b" when my bean for class b is called. Below is what i tried. "i am on one page where i selected 10 products and on calling multi select event listener i got number of products in class a." but when bean is initialised for class b there i am getting null instead of value i need from class a.
Class A{
private string test;
public void setTest(String test)
{
this.test=test} //value is setting up on an event like
multi-select of products
public String getTest()
{
return test;} . //value is coming here
}
Class B{
private String attribute;
public void setAttribute(String attribute) //getting null
{
this.attribute=attribute}
public String getAttribute()
{
return attribute;}
}
<bean id="classB" class"B">
<property name="attribute">
<bean factory-bean="A" factory-method="getTest"></bean>
</bean>
You can define two separate beans for class A and class B as there is no dependency in both the classes as I understood from your problem statement.
After that, inject class A as property in class B will solve your issue.

Make a form field selection values dependent on another field value

I am editing the AP301000 screen, Bills and Adjustments, in a customization project.
I added two new fields to the form, which are both in the APRegisterExt class.
1. PONbr
2. ReceiptNbr
When a user selects a PO number, I want the ReceiptNbr selection values to be restricted to only the receipt records which have the same PO number.
I tried using a PXSelector attribute on ReceiptNbr, but because the PONumber is in an extension class, I cannot use Current<> to access this field.
Any ideas?
On your second CustomField's Selector attribute definition use Current<> statement for filtering, see below:
#region UsrCustomField1
[PXDBInt]
[PXUIField(DisplayName="CustomField1")]
[PXSelector(typeof(Search<DAC.Field>),
typeof(DAC.Field),
typeof(DAC.Field),
SubstituteKey= typeof(DAC.Field))]
public virtual int? UsrCustomField1 { get; set; }
public abstract class usrCustomField1 : IBqlField { }
#endregion
#region UsrCustomField2Dependent
[PXDBInt]
[PXUIField(DisplayName="CustomField2Dependent")]
[PXSelector(typeof(Search<DAC.Field, Where<DAC.Field, Equal<Current<UsrCustomField1>>>>),
typeof(DAC.Field),
typeof(DAC.Field),
SubstituteKey= typeof(DAC.Field))]
public virtual int? UsrCustomField2Dependent { get; set; }
public abstract class usrCustomField2Dependent : IBqlField { }
#endregion
Then on your ASPX file make sure you have added CommitChanges=True and AutoRefresh=true properties, see below:
<px:PXSelector runat="server" ID="CstPXSelector2" DataField="UsrCustomField1" CommitChanges="True" AutoRefresh="True" />
<px:PXSelector runat="server" ID="CstPXSelector1" DataField="UsrCustomField2Dependent" CommitChanges="True" AutoRefresh="True" />

Make an XML element mandatory

Here I am currently working on a program that will serialize an XML file asp.net object. My problem is that I can not find the attribute that makes it mandatory to have a tag in the XML file.
You will find below the definition of my object.
[System.SerializableAttribute()]
public class EchangeIdentification
{
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("agrement")]
public string Agrement{ get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("cvi")]
public string NumeroCvi { get; set; }
/// <remarks/>
[Required]
[XmlElement("siret")]
public string Siret { get; set; }
}
As far as I know, there is no way to declaratively force elements and attributes to be required using the XmlSerializer. C# object properties that can be null are always optional.
A few observations
[Serializable] is not used by the XML Serializer.
There is no way to make it required using the XML Serializer, but if you don't have to use XmlSerializer? DataContractSerializer provides the following option:
[DataMember(IsRequired = true)]
You don't need the "Attribute" name in the code, your code could look like this
[Serializable]
public class EchangeIdentification
{
[XmlElement("agrement")]
public string Agrement{ get; set; }
[XmlElement("cvi")]
public string NumeroCvi { get; set; }
[XmlElement("siret")]
public string Siret { get; set; }
}
Define "serialize an XML file asp.net object" and "makes it mandatory to have a tag in the XML". It all depends on how you're using this class.
Are you using it as a deserialization container, into which you will deserialize XML you receive? Then create an XSD schema, and validate the incoming XML before (or rather during) serialization. See Validating an XML against referenced XSD in C#.
On the other hand, if the user of this code is assigning properties of an instance of this class at runtime, and you serialize it through XmlSerializer, you could validate the output after serializing. See the linked question above, and Can I fail to deserialize with XmlSerializer in C# if an element is not found?.
Alternatively, you could implement serialization callbacks and create a validation method that throws an exception if [Required] properties have the default value for their type.
I'd go with the XSD route either way.

Why is my OData V4 Identifier not working on my ASP.NET dataservice?

I have a Problem using my OData V4 Service in ASP.NET when using integer keys. I am not using Entity Framework, as I get my data from a SOAP service.
Here is my data class:
public class RecipeDto
{
public RecipeDto();
public RecipeDto(string name);
public RecipeDto(int ident);
public string Description { get; set; }
public int Ident { get; set; }
public string Name { get; set; }
public List<RecipeVersionDto> Versions { get; set; }
}
And I set my key using fluent API:
var rtdto = builder.EntitySet<RecipeTemplateDto>("AgentConfigTemplates").EntityType
.HasKey(r => r.Ident)
.HasMany(r => r.Versions);
Here is my metadata on my service:
<EntityType Name="RecipeTemplateDto">
<Key>
<PropertyRef Name="Ident"/>
</Key>
<Property Name="Ident" Type="Edm.Int32" Nullable="false"/>
<Property Name="Description" Type="Edm.String"/>
<Property Name="Name" Type="Edm.String"/>
<NavigationProperty Name="Versions" Type="Collection(Ifmdatalink.Linerecorder.Backend.PlugIn.dto.RecipeTemplateVersionDto)"/>
</EntityType>
Now I would expect to get the first entry of my entity set by using this query:
GET http://localhost:13917/my.svc/AgentConfigTemplates(1)
But I always get the complete list.
Why is this happening and how can I get the first entry?
Do I have to extend my odata controller somehow?
If I put my key in quotes I get a bad request response.
The answer is neither in the model nor in the fluent api definition. It is a problem of the controller. An OData Controller needs to implement two get methods:
public async Task<IQueryable<AgentVersionDto>> Get()
public SingleResult<AgentDto> Get([FromODataUri] int key)
This covers a get for the whole entity set and for a single entry. If the latter is not implemented the odata service in webapi 2 will always return the whole list.

Discriminator column nhibernate

I have a discriminator column in the which i need to use for select insert and update. I need to update and select the Employee type. I have following code in the mapping xml file.
<discriminator column="EmployeeType" type="String"/>
<property name="EmployeeType" column="EmployeeType" update="false" insert="false" type="String" />
Please assist me
It is not possible to do what you want to do because changing the discriminator value would change the class type.
The only possible solutions are to:
Create a new instance of the class you want and copy the values from the other class instance.
Don't use inheritance and discriminators to store the type information. Use an enumerated property instead. This will allow you to change the type of the employee on the fly.
Update the discriminator using an SQL Update statement.
An example of why it does not make sense to this is the following. Say you have the following classes:
public abstract class Animal
{
public virtual Guid id { get; set; }
public virtual string AnimalType { get; set; }
...
}
public class Dog : Animal
{
public virtual bool loves_walkies { get; set; }
}
public class Cat : Animal
{
public virtual bool is_agile { get; set; }
}
With the mapping something like
<class name="Earth.Animal">
...
<discriminator column="AnimalType" type="String"/>
<property name="AnimalType" type="String" />
<subclass name="Earth.Cat" discriminator-value="Cat">
<property name="loves_walkies" />
</subclass>
<subclass name="Earth.Dog" discriminator-value="Dog">
<property name="is_agile" />
</subclass>
</class>
Now if NHibernate allowed you to do something like the following:
var dog = session.Get<Dog>(guid);
dog.AnimalType = "Cat";
session.SaveOrUpdate(dog);
What would the results be? Does NHibernate persist the loves_walkies property because the object is a Dog, but look the discriminator says it is a cat so it needs to persist the is_agile property.
To avoid this confusion NHibernate make the discriminator column read-only.
This question has been asked before, please see the links below for further reading:
https://groups.google.com/forum/?fromgroups=#!topic/nhusers/_Qqi4WCu2Bk
NHibernate - Changing sub-types

Resources