I have a requirement that all Contacts must also be users. I have met this requirement by letting Contact inherit from SecurityUser and it works nicely thanks to your new object instance permission criteria.
The problem is that I now cannot use Domain Components because the Contact persistent object cannot reference the domain components.
Is there a workaround for this? Can I perhaps somehow convert Contact to a domain component and still use it as a user in the new security system? Alternatively is there some way that I can let my Client domain component reference the Contact persistent object in one to many relationship?
I have attached a sample solution. Ideally I would like both Client and Contact to be domain components. If this is not possible would it at least be possible to convert Client to a domain component and still have it reference the Contact collection?
How to reference a domain component (DC) from an XPO business class and vice versa
Answers approved by DevExpress Support
Hello Trentin,
>>
The problem is that I now cannot use Domain Components because the Contact persistent object cannot reference the domain components.
<<
To implement a reference to the DC interface in a regular business object, declare a hidden property of the Guid type mapped to a foreign key column and implement the IObjectSpaceLink interface. The IObjectSpace component is necessary to manage DC objects, which cannot be managed using the Session component.
Here is the code snippet demonstrating the implementation details.
C#[NavigationItem]
[DomainComponent]
public interface TestInterface {
string Name { get; set; }
}
[DefaultClassOptions]
public class TestClass : BaseObject, IObjectSpaceLink {
public TestClass(Session session) : base(session) { }
private TestInterface fRef;
[PersistentAlias("[Alias_Ref]")]
public TestInterface Ref {
get {
if (fRef == null && Alias_Ref.HasValue) {
fRef = ObjectSpace.GetObjectByKey<TestInterface>(Alias_Ref.Value);
}
return fRef;
}
set {
fRef = value;
if (value == null) {
Alias_Ref = null;
} else {
Alias_Ref = (Guid)ObjectSpace.GetKeyValue(value)
}
}
}
[Persistent("Ref")]
[Browsable(false)]
public Guid? Alias_Ref {
get { return GetPropertyValue<Guid?>("Alias_Ref"); }
set { SetPropertyValue("Alias_Ref", value); }
}
public IObjectSpace ObjectSpace { get; set; }
}
Take special note that if you do not need all this code if you want to reference an XPO class from a domain component - simply declare a regular property in your interface as follow:
C#[DomainComponent]
public interface TestInterface2 {
MyXpoClassType XpoReference { get; set; }
}
True associations like between regular XPO models are not possible.
However, it is possible to declare a weak IList<YourPersistentType> YourCollection {get;} property and return a required collection from the Get_YourCollection method of a domain logic class. You can do this via the IObjectSpace.GetObjects method.
I want to again emphasize that this scenario is a bit unnatural as domain components were not designed to be mixed with XPO models by default. These solutions (not very straightforward) are possible only because DC models are generated into XPO models at runtime. I would not recommend you use such mixing in many places of your app as it is recommended to go either with XPO or with DC without mixing.
I hope you find this information helpful.
See Also:
Security - Support domain components in the new security system (Client-Side UI and Integrated modes)
Custom "Improved Security" Users, Roles, and Permissions using Domain Components
Domain Components - Persistent Interfaces - Help
Thanks,
Dennis
I am really looking to have your TestInterface example like this:
[NavigationItem]
[DomainComponent]
public interface TestInterface {
string Name { get; set; }
IList<TestClass> Tests { get; set; }
}
Alternatively is it possible to implement SecurityUser as a Domain Component so that it can be referenced by other Domain Components? In other words would it all be possible to pass a Domain Component into the SecurityStrategyComplex constructor?
Hello,
>>Alternatively is it possible to implement SecurityUser as a Domain Component so that it can be referenced by other Domain Components?
Sure, it is possible and it seems to be the best solution here. Please wait for the Security - Support domain components in the new security system (Client-Side UI and Integrated modes) suggestion implementation. We are currently working on it.
Thanks,
Dennis
Other Answers
I have dealt with this by registering the Domain Component with the SecuritySystemUser class (or SecurityStrategy) as base class.
I attach an example solution.
PS: Yeah, I know that the question is a bit old, but I wanted to share my solution in case someone is having the same problem today.
Hello Santiago,
I appreciate your taking time to share your solution with other XAF customers.
BTW, alternatively it is possible to implement fully DC-based versions of security user, role and other classes as demonstrated in our SecurityDemo:
C:\Users\Public\Documents\DXperience 13.1 Demos\eXpressApp Framework\SecurityDemo\CS\DCSecurityDemo.Module\Security\
Because DC is not further developed, we think about a path to migrate step by step away from dc to standard xpo. Is this post still state of the art how to mix dc and standard xpo or is there more information how to move away from dc?
txs Frank
@fMerian: If you are happy with DC and do not need new features, you can continue using DC as long as you wish. Otherwise, you may find the following article helpful: How to migrate Domain Components (DC) interfaces to pure XPO classes.