mapstruct: mapping from two different fields - mapstruct

How to make mapping from two different fields? I need to set b.url to a.x.y.z.url if it exists otherwise to a.k.l.m.url:
b.url = exists(a.x.y.z.url) ? a.x.y.z.url : exists(a.k.l.m.url) ? a.k.l.m.url : defaultValue
Expression might help but it will be quite long expression if I check all nested fields for null, like "a != null && a.getX() != null && a.getX().getY() != null && a.getX().getY().getZ() != null && a.getX().getY().getZ().getURL() != null ? a.getX().getY().getZ().getURL() : ..."
Thanks,
Pavel

You can use MapStruct #AfterMapping to gain access to the mapping object.
#AfterMapping
protected void mapUrl(B b, #MappingTarget A a) {
//You will do your logic here
}
Theoretically you could do it via an expression by declaring you Mapper as an abstract class and defining a getUrl(A a) method. They in your expression you could call getUrl(a).
I would suggest to use the #AfterMapping, as it is cleaner (in my opinion)

Related

EF Dynamic Filters delegate expression

We are using EF Dynamic filters (ASP.NET MVC 5 app)
https://entityframework-dynamicfilters.net/overview
The filter below is working, but set only once.
builder.Filter("IMultiOrganization", (IMultOrganization d) => ((d.TenantId == GlobalAppVariables.IssuerId) && (d.IsShared == true)) || ((d.IsShared == false && d.AzureObjIdentifier == GlobalAppVariables.AzureObjIdentifier)));
The variables 'IssuerId' and 'AzureObjIdentifier' are dynamic session variables, those are changing all the time. This causes problems and I would like the filter to use those variables straight from the session.
According to the documentation this is caused because this filer isn't a delegate expression.
Filters can be defined on a specific entity class or an interface by providing a specific value, e.g. an IsDeleted filter created on an ISoftDelete interface which will automatically filter those entities by applying the condition "IsDeleted==false".
Filter values can also be provided via a delegate/expression instead of a specific value which allows you to change the parameter value dynamically. For example, a filter can be created on the UserID and provided per HTTP request.
We also use delegate filters what indeed is working fine.
builder.EnableFilter("IMultiTenant", () => GlobalAppVariables.AzureObjIdentifier != null || GlobalAppVariables.IssuerId != Guid.Empty);
But I can't get the first filter work as a delegate expression and need a bit help on that.
I found the solution by using parameters within the filter.
First of all I changed the filter which now supports parameters.
builder.Filter("IMultiOrganization", (IMultiOrganization d, Guid tenantId, string azureId) => (d.TenantId == tenantId && d.IsShared == true) || (d.AzureObjIdentifier == azureId && d.IsShared == false), GlobalAppVariables.IssuerId, GlobalAppVariables.AzureObjIdentifier);
Then I call method below in the db context constructor
private void SetMultiOrganizationFilterParams()
{
if (GetFilterEnabled("IMultiOrganization"))
{
this.SetFilterScopedParameterValue("IMultiOrganization", "azureId", GlobalAppVariables.AzureObjIdentifier);
this.SetFilterScopedParameterValue("IMultiOrganization", "tenantId", GlobalAppVariables.IssuerId);
}
}
Source: https://github.com/zzzprojects/EntityFramework.DynamicFilters#changing-filter-parameter-values

Why is manual null check required when ? operator is there in Flutter?

String playerName(String? name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
? checks whether name is null or not, then why is special if (name != null) { condition required?
The String? name means that the parameter name is nullable as you can see lower in the code the if statement then checks if your parameter is not null.
Dart docs definition:
If you enable null safety, variables can’t contain null unless you say they can. You can make a variable nullable by putting a question mark (?) at the end of its type. For example, a variable of type int? might be an integer, or it might be null. If you know that an expression never evaluates to null but Dart disagrees, you can add ! to assert that it isn’t null (and to throw an exception if it is). An example: int x = nullableButNotNullInt!
Link to docs

Is it possible to require only one of two parameters in Dart?

I know that I can require one parameter using #required like below :
class Foo{
String firstParam;
String secondParam;
Foo({#required this.firstParam, this.secondParam});
}
However, I don't know how to require only one of the two parameters without requiring both. I have something that looks like what I want using assert :
class Foo{
String firstParam;
String secondParam;
Foo({this.firstParam, this.secondParam}): assert(this.firstParam != null || this.secondParam!= null);
}
But it doesn't warn me in VS Code and asserts are not used in Release mode.
Is there some way to do it in Dart?
Use this and provide a message for your assertion:
class Foo {
String firstParam;
String secondParam;
Foo({this.firstParam, this.secondParam})
: assert(
(firstParam != null || secondParam != null),
'One of the parameters must be provided',
);
}
Warning if none of the parameters is provided:
I think it's not possible, though you could make both parameters to be required and set explicitly to null if it is needed

ConfigurationElement—Combination of Attributes?

Say I have defined a custom AdapterElement : ConfigurationElement with properties Type, Name and Version. Since Name and Version uniquelly identifies the Type property, I would like to enforce the configuration file to have one of the following structures:
<adapter type="TypeOfAdapter"/>
<adapter name="NameOfAdapter" version="VersionOfAdapter"/>
I could easily mark those three properties with IsRequired = false and let users specify the combination the want. However, the following combinations are not valid and I would like to forbid them:
<adapter type="TypeOfAdapter" version="VersionOfAdapter"/>
<adapter type="TypeOfAdapter" name="NameOfAdapter"/>
Is there any easy way of achieving this?
I had to do a bit of reading around to find answers on this one.
How about adding a PostDeserialise check for validity to your AdapterElement class?
protected override void PostDeserialize()
{
bool isValid = Type != null && Name == null && Version == null
|| Type == null && Name != null && Version != null;
if (!isValid)
{
throw new ArgumentException("Must specify either Type or Name and Version");
}
base.PostDeserialize();
}
According to a blog I found there is no more obvious way of verifying validity of Multiple Attributes on a single configuration section - but it appears to be true for configuation elements too.

Using Expression Trees as an argument constraint

Can I use an Expression Tree as an argument constraint in a FakeIteasy CallTo assertion?
Given a method on an interface with the following signature:
interface IRepository<TEntity>
{
TEntity Single(Expression<Func<TEntity, bool>> predicate);
Being called in code like so:
Flight flight = repository.Single(f => f.ID == id);
I have in mind a unit test doing something like this:
Expression<Func<Flight, bool>> myExpression = flight => flight.ID == 1;
A.CallTo(() => repository.Single(
A<Expression<Func<Flight, bool>>>.That.Matches(myExpression)))
.Returns(new Flight());
However this produces a warning: Try specifying type arguments explicitly.
I am currently having to use the Ignored property which is not ideal.
The "Matches"-method takes a lambda but you're trying to pass it the expression. What are you trying to say with the "Matches"-call? Are you matching on equality? In that case you'd just write:
A.CallTo(() => repository.Single(myExpression)).Returns(new Flight());
If you want to constrain the expression on something else you'd have to pass a predicate of the type: Func<Expression<Func<Flight, bool>>, bool> to the "Matches"-method.
Thanks Patrik,
Examining the expression was exactly what I needed to do, i.e. parse the expression (f => f.ID == id) and execute the Right side of the == to get its runtime value.
In code this looks like this:
A.CallTo(() => flightRepository.Single(A<Expression<Func<Flight, bool>>>.That
.Matches(exp => Expression.Lambda<Func<int>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == 1)))
.Returns(new Flight());
However I can't help thinking that there must be a more elegant way to achieve the same end. I'll leave that for another day though.
Thanks again,
Michael McDowell
I had the same problem while attempting to assert an expression as an argument but I was using Moq. The solution should work for you though as well...
I give most of the credit to this answer to a similar question:
Moq Expect On IRepository Passing Expression
It basically says you can do a ToString() on the expressions and compare them. It is kind of hacky but it only has one downside; the variables names in the lambda expression must match.
Here is an example...
[Test]
public void TestWhichComparesExpressions()
{
// setup
_mockRepository.Setup(x => x.GetByFilter(MatchQuery())).Returns(new List<Record>());
// execute
var records = _service.GetRecordsByFilter();
// assert
Assert.IsNotNull(records);
Assert.AreEqual(0, records.Count());
}
private static Expression<Func<DomainRecord, bool>> MatchQuery()
{
return MatchExpression(ServiceClass.QueryForTheRecords); // constant
}
// https://stackoverflow.com/questions/288413/moq-expect-on-irepository-passing-expression/1120836#1120836
private static Expression<Func<DomainRecord, bool>> MatchExpression(Expression<Func<DomainRecord, bool>> expression)
{
return It.Is<Expression<Func<DomainRecord, bool>>>(e => e.ToString() == expression.ToString());
}
I decided to put the expression into a constant on the class which used it which guaranteed it would be the same in the test if someone changed the lambda expressions's variable names.