Skip to main content
Question

Best Practice for Reusing Functionality and DAC Fields from Another Customization

  • August 27, 2026
  • 12 replies
  • 122 views

Forum|alt.badge.img+2

Hi everyone,

I have a specific functionality implemented in one Acumatica Customization Project.

Now, in another Customization Project, I need to reuse some of the functionality and DAC fields that were introduced in the first customization.

What would be the recommended approach for this scenario?

I would appreciate any recommendations or best practices for structuring customizations in this case.

Thanks!

12 replies

Naveen Boga
Captain II
Forum|alt.badge.img+20
  • Captain II
  • August 27, 2026

@bihalivan15   The recommended approach would generally be to make the first customization a dependency of the second customization, rather than duplicating the DAC fields or functionality.

If the second customization needs to access DAC extensions, graph extensions, or other functionality introduced by the first project, you can reference the first customization's assembly/project and build the second customization against it. This keeps the shared functionality in one place and avoids maintaining duplicate code.

Another option, especially if the functionality is going to be reused across multiple customization projects, is to move the common DAC extensions and business logic into a shared customization library/assembly and have the individual customization projects reference that shared library.

I would avoid copying the DAC fields or implementation from one customization into another, as that can lead to duplicate definitions, upgrade issues, and maintenance problems.

The best structure depends on whether the first customization is always going to be deployed together with the second one. If they are independent/customers may deploy them separately, I'd lean toward a shared library or common customization layer. If the second customization will always depend on the first, treating the first project as a dependency is usually simpler.


Forum|alt.badge.img+5
  • Jr Varsity II
  • August 27, 2026

Hi ​@bihalivan15 ,

Is the DAC field/functionality conceptually common to both customizations?

  • Yes → Move it into a shared/common customization package and let both projects consume it.
  • No, B is an extension of A → Make B dependent on A.
  • Only a small amount of code is shared → Dependency on A may be simpler, but avoid copying the DAC extension.
  • Large amount of common code → Consider a shared customization/library architecture.

The key principle is: don't duplicate DAC extensions or business logic merely because they are currently implemented in another customization project. Keep ownership of the shared DAC fields/functionality in one place and make the dependency explicit.

 

Hope above helps!!


KrunalDoshi
Semi-Pro III
Forum|alt.badge.img+6
  • Semi-Pro III
  • August 28, 2026

Hi ​@bihalivan15,

Is the first customization project compiled into a DLL? If not, I would recommend considering that approach if the functionality is intended to be reused by other customization projects.

You can compile the shared functionality from the first customization into a DLL and then reference that DLL from the other customization projects. This allows you to reuse the existing code and DAC extensions/fields without duplicating the definitions or implementation.

You will also need to make sure that the customization projects are "published in the appropriate order" rather than simply "set the level of first customization before the second," since the exact deployment mechanism can vary and the important concept is that the dependency must be available before the dependent customization is built/published.

This approach has a few advantages:

  • Avoids duplicating code and DAC definitions across customization projects.
  • Provides a clear dependency between the customizations.
  • Makes it easier to maintain common functionality in one place.
  • Allows multiple customization projects to consume the same shared functionality.

The main consideration is version management. Whenever you make changes to the first customization, you should recompile the DLL and make sure that any dependent customization projects are rebuilt against the updated DLL. The updated DLL also needs to be included/deployed wherever the dependent customization is deployed.

If the shared functionality is expected to be reused by several customization projects, I would consider creating a separate common/shared customization DLL library containing only the reusable DACs, DAC extensions, graph extensions, helper classes, and other common functionality. That is generally cleaner than making Customization B depend directly on Customization A, because A may contain unrelated functionality that B doesn't actually need. The individual customization projects can reference that library rather than having one customization project depend on another unnecessarily.

Also, keep in mind that if the shared DAC fields are added through DAC extensions, the dependent customization should not redefine those fields. It should simply reference and use the existing DAC extension from the shared DLL.

This gives you a cleaner dependency structure and makes the customizations easier to maintain and upgrade.

Hope this helps.


darylbowman
Captain II
Forum|alt.badge.img+17

​Is the first customization project compiled into a DLL? If not, I would recommend considering that approach if the functionality is intended to be reused by other customization projects.

@KrunalDoshi For what reason?


KrunalDoshi
Semi-Pro III
Forum|alt.badge.img+6
  • Semi-Pro III
  • August 28, 2026

​Is the first customization project compiled into a DLL? If not, I would recommend considering that approach if the functionality is intended to be reused by other customization projects.

@KrunalDoshi For what reason?

@darylbowman I did not follow the question?


darylbowman
Captain II
Forum|alt.badge.img+17

For what reason would you recommend that the package being depended upon be compiled?


KrunalDoshi
Semi-Pro III
Forum|alt.badge.img+6
  • Semi-Pro III
  • August 28, 2026

@darylbowman,

The main reason I recommend compiling the package being depended upon is to make sure that Project B is referencing a compiled, consistent version of Project A.

For example, if Project A is compiled and its DLL is referenced by Project B, Project B is effectively built against that particular version of Project A. If you subsequently make changes to Project A—especially changes to DACs, DAC extensions, method signatures, or other public members—and update the DLL without rebuilding Project B, Project B may still have been compiled against the previous version of the assembly. This can potentially result in compilation issues, missing members, or unexpected runtime behavior depending on the changes.

Hopefully able to answer your question.


darylbowman
Captain II
Forum|alt.badge.img+17

​If you subsequently make changes to Project A—especially changes to DACs, DAC extensions, method signatures, or other public members—and update the DLL without rebuilding Project B, Project B may still have been compiled against the previous version of the assembly.

The terminology you’re using indicates you’re assuming both projects are being compiled. If neither project is compiled, it’s definitely true that changing A could be a problem for B, but I would argue it’s something that would be caught when publishing, not something that would hit you out of nowhere, and a problem that could be handled with version control just as easily as compiling.


KrunalDoshi
Semi-Pro III
Forum|alt.badge.img+6
  • Semi-Pro III
  • August 28, 2026

​If you subsequently make changes to Project A—especially changes to DACs, DAC extensions, method signatures, or other public members—and update the DLL without rebuilding Project B, Project B may still have been compiled against the previous version of the assembly.

The terminology you’re using indicates you’re assuming both projects are being compiled. If neither project is compiled, it’s definitely true that changing A could be a problem for B, but I would argue it’s something that would be caught when publishing, not something that would hit you out of nowhere, and a problem that could be handled with version control just as easily as compiling.

That's a fair point. I may have been too specific in my terminology around compiling both projects.

My main point was that, if Project A is being compiled into a DLL and Project B is consuming that DLL, I would want to make sure that B is using the same version of A that it was developed/tested against.


Jhon Reeve Penuela
Varsity I
Forum|alt.badge.img

Building on what ​@Naveen Boga , ​@Rakshanda , ​@KrunalDoshi , and ​@Daryl Schlotthauer already covered — the dependency-vs-shared-library split is the right way to frame the decision. A couple of implementation details that tend to trip people up once you actually start writing the code:

If the two customizations will always ship together, publish the first project, then build the second against it — but be careful how you extend the DACs. A common mistake is declaring a second, independent PXCacheExtension<SomeDAC> in Project B that adds fields to the same DAC Project A already extended. That fails at publish (Acumatica treats it as a duplicate member if the field names collide) and, even when the field names differ, it leaves you with two unrelated cache extensions on the same DAC with no explicit relationship between them. Instead, have Project B extend Project A's extension class:

// Project A
public class SomeDACExt : PXCacheExtension<SomeDAC>
{
public abstract class usrFieldA : BqlString.Field<usrFieldA> { }
[PXDBString(50)]
public virtual string UsrFieldA { get; set; }
}

// Project B — extends A's extension, not a sibling extension of SomeDAC
public class SomeDACExt2 : PXCacheExtension<SomeDACExt>
{
public abstract class usrFieldB : BqlString.Field<usrFieldB> { }
[PXDBString(50)]
public virtual string UsrFieldB { get; set; }
}

This makes the dependency explicit and compiler-enforced, and it guarantees Project B literally cannot compile without Project A already published. Same idea applies at the graph level — if Project A already has a graph extension with event handlers on a DAC, Project B should extend that graph extension rather than add a second independent one with an overlapping RowSelecting/RowPersisting on the same field, which just creates ordering ambiguity about which handler fires first.

If the two need to deploy independently (different clients, different release cycles, or you're packaging this for resale), pull the shared DAC extensions and business logic into their own "library" customization project with a clean, minimal public surface — public extension classes, public constants for field/view names, nothing internal exposed. Publish that as a prerequisite package and have both consumers reference it. Functionally this is the same mechanism as above (extension-of-extension), just organized so the shared piece has its own lifecycle and versioning instead of living inside one of the two feature projects.

A few things worth calling out regardless of which pattern you pick:

  • Never redeclare the same DAC field in two independently-maintained projects touching the same table — even identical attributes on both sides is a landmine, since only one wins depending on publish order and you get silent, hard-to-diagnose behavior differences between environments.
  • Test-publish both projects together on a sandbox before promoting anything to production. A missing or misordered dependency almost always shows up only as a publish-time compile failure, and on SaaS-hosted tenants the publish log is the only diagnostic you get — there's no SSMS/VS debugging to fall back on.
  • Document the dependency explicitly (project description field, or a short README bundled in the customization package) so whoever maintains this next knows Project B won't compile without Project A published first. This is easy to forget six months later when someone tries to move just one of the two projects to a new tenant.

Curious whether you're leaning toward "always deployed together" or need independent release cycles for these two — that's really what decides which of the two patterns to commit to.


darylbowman
Captain II
Forum|alt.badge.img+17

 ​@Jhon Reeve Penuela - I’m really hoping this isn’t copied and pasted from ChatGPT, but I have my doubts because 1) it sounds like AI and 2) as far as I have been able to determine, this is impossible.

Instead, have Project B extend Project A's extension class:

// Project A
public class SomeDACExt : PXCacheExtension<SomeDAC>
{
public abstract class usrFieldA : BqlString.Field<usrFieldA> { }
[PXDBString(50)]
public virtual string UsrFieldA { get; set; }
}

// Project B — extends A's extension, not a sibling extension of SomeDAC
public class SomeDACExt2 : PXCacheExtension<SomeDACExt>
{
public abstract class usrFieldB : BqlString.Field<usrFieldB> { }
[PXDBString(50)]
public virtual string UsrFieldB { get; set; }
}

 I get a compiler error:

Care to defend this?


Jhon Reeve Penuela
Varsity I
Forum|alt.badge.img

Hi ​@darylbowman, sorry for the earlier misunderstanding — I assumed it matched what I had in mind, but I'll correct it on my end.

Based on my experience in development, this is the approach I usually take, though I'm not sure if it's best practice:

 

1. First Customization — [Customization #1]

2. Second Customization — [Customization #2]

My Second Customization references the First Customization

and reuses the custom field from the First Customization in the Second Customization.

 

Apologies again for passing along incorrect information earlier.

 

Thanks.,