I have been scratching my head for some time trying to figure out why my business rule wasn't setting a Guid property on my business object, since I had done this sort of thing before. However, it occurred to me that the other properties I was setting were strings and primitive values.
So, I copied and pasted my UserId property (a guid) and made it into a string. Then I wired up the new property to my business rule, and it works. The thing is, I need it to be a Guid.
I tried both the AddOutValue and LoadProperty techniques to set the output of my rule, but it doesn't function with Guid in either case. So is there something special I have to do to make this work, or did I find a bug?
Here are my properties (Identical in every way except datatype):
public static readonly PropertyInfo<Guid> UserIdProperty = RegisterProperty<Guid>(c => c.UserId);
public Guid UserId
{
get { return GetProperty(UserIdProperty); }
private set { LoadProperty(UserIdProperty, value); }
}
public static readonly PropertyInfo<string> UserIdStringProperty = RegisterProperty<string>(c => c.UserIdString);
public string UserIdString
{
get { return GetProperty(UserIdStringProperty); }
private set { LoadProperty(UserIdStringProperty, value); }
}
And this is my business rule:
public class UserHasConfirmedAccountRule
: PropertyRule
{
public UserHasConfirmedAccountRule(
Type modelType,
ILocalizedStringProvider localizedStringProvider,
IPropertyInfo emailAddressOrPublicNameProperty,
IPropertyInfo tenantIdProperty,
IPropertyInfo userIdProperty,
IUserAccountRepository userAccountRepository
)
: base(emailAddressOrPublicNameProperty, modelType, localizedStringProvider)
{
if (emailAddressOrPublicNameProperty == null)
throw new ArgumentNullException("emailAddressOrPublicNameProperty");
if (tenantIdProperty == null)
throw new ArgumentNullException("tenantIdProperty");
if (userIdProperty == null)
throw new ArgumentNullException("userIdProperty");
if (userAccountRepository == null)
throw new ArgumentNullException("userAccountRepository");
this.emailAddressOrPublicNameProperty = emailAddressOrPublicNameProperty;
this.tenantIdProperty = tenantIdProperty;
this.userIdProperty = userIdProperty;
this.userAccountRepository = userAccountRepository;
InputProperties = new List<IPropertyInfo> { emailAddressOrPublicNameProperty, tenantIdProperty, userIdProperty };
AffectedProperties.Add(userIdProperty);
}
private readonly IPropertyInfo emailAddressOrPublicNameProperty;
private readonly IPropertyInfo tenantIdProperty;
private readonly IPropertyInfo userIdProperty;
private readonly IUserAccountRepository userAccountRepository;
protected override void Execute(CslaLibrary.Rules.RuleContext context)
{
var emailAddressOrPublicName = (string)context.InputPropertyValues[emailAddressOrPublicNameProperty];
var tenantId = (int)context.InputPropertyValues[tenantIdProperty];
bool exists = false;
Guid userId = Guid.Empty;
if (!string.IsNullOrEmpty(emailAddressOrPublicName) && tenantId > 0)
{
userId = userAccountRepository.HasConfirmedAccount(tenantId, emailAddressOrPublicName);
if (userId != null && !userId.Equals(Guid.Empty))
{
exists = true;
context.AddOutValue(userIdProperty, userId.ToString());
//var target = (ResetPassword)context.Target;
//LoadProperty(target, userIdProperty, userId.ToString());
}
}
if (!exists)
context.AddErrorResult(GetMessage());
}
}
Note that I am using a subclass of PropertyRule, but I changed it to the CSLA BusinessRule type and still got the same result. Also note the code above is the version that works - I wouldn't use .ToString() when trying to set a guid.