Since AX 2012 brought in the concept of models I have been very interested in utilising them to their full potential with our clients and our products. With certain things such as entirely new tables, classes, forms etc, the model concept works very well. It even works well when it comes to individual components on forms or new fields or methods as they are all regarded as individual objects in AX that can be plugged in and out of AX with models.
Where things start to become a bit harder is on shared objects such as standard methods etc. So how do we overcome some of these challenges. Hopefully over the next while I will post some useful design patterns and tools that one can use to keep one’s models clean and separated where at all possible. An added bonus of keeping your code separate is that it make performing Cumulative updates or 3rd party updates alot easier as there is less overshadowing.
One of the most useful tools for keeping models separate is the new Eventing functionality in Dynamics AX 2012. Eventing has a number of benefits, but in regards to model management eventing allows one to keep your code (the event handler method) in a separate model to calling class as well as keeping the event subscription that calls your code in your separate model.
Eventing on Table Methods e.g. initFrom
Using event handlers and subscriptions on table methods are one of the areas that are very useful for model management. For example you may have added new fields to a standard table such as PurchTable that you would like to initialise as part of the “initFromRFQTable” method without overshadowing standard AX code. Using event an event handler you could do the following;
1. Create New class e.g. MyEventHandler
2. Add a new static method to the class e.g. initFromRFQTable that accepts an XppPrePostArgs object as a parameter.
3. Get a reference to the calling object, in this case the PurchTable e.g. PurchTable purch = ppArgs.getThis();
4. Get a reference to the calling method’s parameter e.g. _purchRFQTable
5. Perform any initialisation that is necessary e.g. purch.MyField = rfq.MyField;
public static void initFromRFQTable(XppPrePostArgs ppArgs)
PurchTable purch = ppArgs.getThis();
PurchRFQTable rfq = ppArgs.getArg('_purchRFQTable');
purch.MyField = rfq.MyField;
Note that this method has access to all the parameters of the PurchTable::initFromRFQTable as well as access to the PurchTable object itself, so you can perform close to anything that you would be able to perform in the method itself.
For a direct example look at how Microsoft has done this for localisations on the PurchTable’s initFromVendTableMethod.
In the next few weeks I’ll publish more model management tools, tricks and design patterns. If you have any of your own please let me know as well.
As you may be aware by now, AX allows one to create users of type “active directory group” which if setup will auto-create users who belong to that group when they try to login. Furthermore users (whether auto-created or manually created) who belong to these groups will inherit the security permissions assigned to these groups.
One challenge however is, to debug this. I.E. Finding out which users are members of specific groups or what groups a specific user belongs to. My previous post was about how to determine ownership via command line. After a bit of reflection I thought this may be better and more useful to have this functionality directly within AX. Using Attached is an XPO with the relevant code (use at your own risk).
Basically it adds a class to AX as well as a lookup menu item to UserListPage form and the User form.
Please let me know your comments.
Here is a sample job if you don’t want to download the full project. It prints all groups for a user.
static void adGroups(Args _args)
CLRObject groups, enum;
System.String domain, username1,groupName;
Userid userId = curUserId();
permission = new InteropPermission(InteropKind::CLRInterop);
yourDomain = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType::Domain);
// find your user
userInfo = xUserInfo::find(false, userId);
domain = UserInfo.networkDomain;
username1 = UserInfo.networkAlias;
user = System.DirectoryServices.AccountManagement.UserPrincipal::FindByIdentity(yourDomain, username1);
// if found - grab its groups
if(user != null)
groups = user.GetAuthorizationGroups();
enum = groups.GetEnumerator();
p = enum.get_Current();
groupName = p.get_Name();
groupN = groupName;
As you may all be aware, AX 2012 offers certain ability to manage your Dynamics AX 2012 users via Active directory groups. Hopefully more on that later. (Check out this post in the meantime http://blogs.msdn.com/b/dynamics-coe/archive/2013/01/13/using-windows-ad-groups-for-user-management-in-ax2012.aspx)
The one problem however is that it becomes quite difficult to trouble shoot security settings. For example how to determine whether a user is actually part of an active directory user group. If you are not a domain admin you can try and use the following two command prompt instructions
1. To detemine an individual user’s groups
net user /domain [username]
e.g.: net user /domain jonathanhalland
2. To detemine all users belonging to a specific group
net group /domain [groupname]
e.g.: net group /domain axrequisitioncreators