Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Feature: Allow for mapping properties containing periods by JMolenkamp · Pull Request #777 · MapsterMapper/Mapster · GitHub
Skip to content

Feature: Allow for mapping properties containing periods - #777

Closed
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development
Closed

Feature: Allow for mapping properties containing periods#777
JMolenkamp wants to merge 2 commits into
MapsterMapper:developmentfrom
JMolenkamp:development

Conversation

@JMolenkamp

@JMolenkampJMolenkamp commented Feb 25, 2025

Copy link
Copy Markdown
Contributor

The InvokerModel stores the property path as a period joined string. When building the expression for a property path, this string is split on the periods, which makes it impossible to have a property name that contains periods.

Obviously, this is kinda obscure, but I actually ran into this issue. It is possible to have a property name with a period when dynamically building types where pretty much all naming restrictions go out of the window, demonstrated in this test.

With this PR, instead of storing a period joined string, the path is stored as a string array. This allows for storing a property name with a period as it is not split on usage. The tests still succeed, except for No_Errors_Thrown_With_Default_Configuration_On_Unmapped_Primitive, which failed to begin with.

If this change is considered, a skeptic review is required, even though the tests succeed. For now, this is just my initial attempt.

For some background:
Our applications frequently have to communicate with industrial devices, for which the OPC UA protocol is often used. When reading or writing some structured data, an application type requires mapping to some node hierarchy provided by the OPC UA server. The configuration for this mapping is external, such that changes in property names/types or even structure do not require a rebuild of the application. Based on the configuration, types are built dynamically and Mapster is configured to map between the application type and the dynamic type. I am not really up to date with the naming restrictions on OPC UA nodes, but usage of periods is allowed, at least in some places.

…el to allow for mapping properties that contain periods
@DocSvartz

Copy link
Copy Markdown
Contributor

Hello @JMolenkamp Excellent work!

  1. Your test only checks that the configuration compiles successfully. If possible, add tests that check that the data is transfered successfully. (_sourse.Adapt() and _sourse.Adapt(_destination));

  2. Have you checked the functionality of your solution when these Properties are used as constructor parameters?

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Hi @DocSvartz,

  1. Compilation is where the exception arose in my situation, which is why this test ends here.
    I will add some further testing.

  2. I do not think so. At this point, I only ensured that the existing tests still succeeded and that no exception was thrown on compilation (my use case).
    Also, I am not quite sure about what you mean with using these properties as constructor parameters.

@DocSvartz

DocSvartz commented Feb 26, 2025

Copy link
Copy Markdown
Contributor

@JMolenkamp I meant that if the constructor parameters in your cases can have names with dots, then you should pay special attention to this.

public class Destination
{
public Destination (string "Some.Property.With.Periods")
}
var destination = new ( source."Some.Property.With.Periods");

They may not mapping, even though the Properties with the same names will be mapping.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz Got it. It won't be an issue in my case, the dynamically created types have a default constructor and each property both has a getter and a setter. I might take a look though.

@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz
Added some tests:

  • Mapping to and from a property containing a period does work
  • Mapping to a constructor parameter containing a period does work
  • Configuring a mapping using a property path string does not work, as it is still split on the periods
  • Mapping to a dictionary key containing periods does not work, also didn't work originally. This one is probably not really a part of this PR, but I wanted to take a look at it anyway.

The latter two gave me an idea to try a different approach and keep the period joined string on the InvokerModel.
Instead of only using the parts after splitting as member names, it might be possible to try out combinations of consecutive parts when members for singular parts are not found. Not really sure what this would involve, but I might take a shot.

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@JMolenkamp

JMolenkamp commented Feb 27, 2025

Copy link
Copy Markdown
ContributorAuthor

@DocSvartz

I tried the alternative approach which turns out to be less impactful and might be preferred.
The test mentioned above does also succeed with this change.
See this branch

Some ambiguity might be possible though, what should "A.B.C" reference:

classSource{publicChildA.B{get;set;}publicintA.B.C{get;set;}}classChild{publicintC{get;set;}}

A risk of building dynamic types, I guess?

Comment threadsrc/Mapster.Tests/WhenMappingMemberNameContainingPeriod.cs
@DocSvartz

This comment was marked as duplicate.

@JMolenkamp
JMolenkamp marked this pull request as draft March 11, 2025 09:24
@JMolenkamp

Copy link
Copy Markdown
ContributorAuthor

Moved to draft in favor of #781

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JMolenkamp@DocSvartz