This is not necessarily specific to ActionScript 3 but I could not think off the top of my head how you would access an instance via string or even if that is possible.
What I have going on is a function in one scene being passed a String which in my case is the name of a particular instance of a movie clip. Is there a way to use that String to access that instance on that scene, IE being passed the string I could change the alpha of that instance which matches the name of the string passed.
Thank you
basically, it is possible to access all public instances of an object/a scene by doing the following:
myMovieClip["myInstance"]
This is equivalent to
myMovieClip.myInstance
So, when you pass a string to a function in order to access a particular instance of that scene, you could, for example, do the following:
function myFunc(name:String, alpha:Number):void {
myMovieClip[name].alpha = alpha;
}
Hope that helps!
Related
Can we use value object in command ?
Suppose I have a Shop (aggregate) in which there is one value object Address.
In the value object constructor Address ,I was put the some validation logic for address.
So if I am using that Address object in command (CreateShopCmd) , then it get validated at the making of command , but What I want or Read that validation should be present in command handler.
But problem is that , I have to put that validation again in command handler (Since validation is already present in it Address constructor) and if I am not putting that in command handler , then the validation will occur when I am making the Address object in event handler and assign to Shop aggregate(Which is incorrect)
So, please guide me.
Below are code example
#Aggregate
#AggregateRoot
public class Shop {
#AggregateIdentifier
private ShopId shopId;
private String shopName;
private Address address;
#CommandHandler
public Shop(CreateShopCmd cmd){
//Validation Logic here , if not using the Address in
// in cmd
//Fire an event after validation
ShopRegistredEvt shopRegistredEvt = new ShopRegistredEvt();
AggregateLifecycle.apply(shopRegistredEvt);
}
#EventSourcingHandler
public void on(ShopRegistredEvt evt) {
this.shopName = evt.getShopName();
//Validation happend here if not put in cmd at the time of making
//Address object - this is wrong
this.address = new Address(evt.getCity(),evt.getCountry(),evt.getZipCode())
}
}
public class CreateShopCmd{
private String shopId;
private String shopName;
private String city;
private String zipCode;
private String country;
}
public ShopCreatedEvent{
private String shopId;
private String shopName;
private String city;
private String zipCode;
private String country;
}
There is nothing conceptually wrong with using Value Objects in Commands or Events. However, you should use them with caution.
The structure of a Message may change over time. If you have used Value Object excessively inside your messages, it may become less clear how a change in one of the value objects changes the structure of different messages.
For Value Objects that represent a "common" concept, such as an Address, this is not so much of a problem. But as soon as the Value Objects become more domain-specific, this may come up as an issue.
This is a very good question and I have been thoroughly thinking about embedding value objects in commands or not. I came to the conclusion you should definitely not use Value Objects in commands:
Commands are part of the application layer, they are supposed to work as simple as possible, avoiding any typed objects, and work best using literal (think serialization). What happen when an external system wants to plugin on your hexagon (application layer) and send commands to your application, do they need your command library to be able to use the objects and the structure defined ? Hell no ! You don't want that, so keep command simple.
Another reason is, as DmitriBodiu said, VO contains business logic and validation, they belong to the domain layer, do not ever put them in commands. Application service will do the translation, and be responsible of throwing validation error to any non conforming commands at the client.
There is nothing wrong in your design, its actually how Vaughn Vernon (the author of Implementing Domain Driven Design - IDDD book) did in his repository, you might want to check the application layer at this link:
https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_identityaccess/src/main/java/com/saasovation/identityaccess/application/IdentityApplicationService.java
Notice how he reconstruct every objects from flat commands to value object belonging to the domain layer:
#Transactional
public void changeUserContactInformation(ChangeContactInfoCommand aCommand) {
User user = this.existingUser(aCommand.getTenantId(), aCommand.getUsername());
this.internalChangeUserContactInformation(
user,
new ContactInformation(
new EmailAddress(aCommand.getEmailAddress()),
new PostalAddress(
aCommand.getAddressStreetAddress(),
aCommand.getAddressCity(),
aCommand.getAddressStateProvince(),
aCommand.getAddressPostalCode(),
aCommand.getAddressCountryCode()),
new Telephone(aCommand.getPrimaryTelephone()),
new Telephone(aCommand.getSecondaryTelephone())));
}
Commands must not contain business logic, so they cannot carry a value object.
I wouldn't suggest using Value Objects in commands. Cause your commands are part of the application layer, but Value Objects are kept in Domain Layer. You can use your ValueObjects in DomainEvens though. Because if domain model changes, modification of your domain event wouln't be that painful, cause the modification is done in the same bounded context. You should never use ValueObjects in integration events though.
Short answer: Have you ever thought about Integer, String, Boolean, etc.? Those are Value Objects, too. The only difference is, that you didn't create them yourself. Now try to build a Command without any Value Objects ;-)
Long answer:
In general I don't see any issue with Value Objects within Commands. As long as you follow a few simple guidelines:
The most important code in your application is your Domain Model. The Domain Model defines the data structures it expects for Command handling. This means: The only reason to change your Command Model is if your Domain Model requires this change. The same applies to your Value Objects: Value Objects only change if this change is required by your Domain Model. No exceptions!
Commands can in general fail either because of business constraints, or because of invalid data (or because of optimistic locking, or whatever).
As said above: Integers and Strings are Value Objects, too. If you only use basic types within your Command, it will already throw an exception if you try new SetAgeCommand(aggId, "foo"), because String cannot be assigned to int. The same applies if you don't provide an Aggregate ID to your UpdatePersonCommand. These are no business constraints, but instead very basic data and type validation. Your Command will never be created if you pass malformed data.
Now let's say you have a PersonAge Value Object. I doesn't matter where you construct this object, because in any case it must throw an Exception if you try to construct it with a negative number: -5 cannot be assigned to PersonAge - looks familiar? As long as you can make sure that your code created those Value Object instances, you can know for sure that they are valid.
Business rules should be checked by the Command Handler within your Domain Model. In general business constraints are specific to your Domain, and most often they rely on the data within your Aggregate. Take for example SendMoneyCommand. Your Money Value Object can validate if it's a valid currency, but it cannot validate if the user's bank account has enough money to execute the transaction. This is a business validation and it's part of your Domain Model.
And a word regarding Events: I'd suggest to only use very basic Value Objects inside your events. For example: String, Integer, Date, etc. Basically every kind of Value Object that will never change. The reason behind it: Business requirements can change. For example: Maybe your Domain Model requires your Address Value Object to change, and it's now required to provide geo-coordinates. Then this will implicitly change your NewAddressAddedEvent. But your already persisted Events didn't have this requirement, though you're unable to construct Address Value Objects from your past event data, because the new Address Value Object will throw an Exception if there are no geo-coordinates provided.
There are (at least) two solutions for this problem:
Versioned Events: After modifying your Address Value Object, you have now a NewAddressAddedEvent_Version2 which uses the new Address Value Object, and you have the old NewAddressAddedEvent which must use a backup copy of the old Address Value Object.
Write a Script that "repairs" your event database by adding geo-coordinates to every Event that uses the Address Value Object. So you can throw away the old NewAddressAddedEvent.
That's OK as long as the value objects are conceptually a part of your message contract, and not used in entities.
And if they are a part of your entity, don't expose them as public properties of your message or you'll be in soop.
I'm trying to write an Oregon Trail type story in java. In one of the methods later on, you are asked to input your name. I've used this to get the name:
Scanner keys = new Scanner(System.in);
String name = keys.nextLine();
I would like to keep referring to the player as the name they entered in other methods and I'm unsure on how to call it. Any help is appreciated.
When you declare
String name = keys.nextLine();
You are creating a string inside the scope of that method. As you probably noticed, it's no longer accessible once the method finishes. Rather than storing the character name in a variable local to that method, you want to save it to a variable in an outside scope.
In Java's object oriented design, the ideal place to put that would be an instance variable for the relevant class. Say you have some master class called "Game". An instance of this class will represent a running game, have methods for interacting with the game, and hold data about the game. You could have an instance variable in Game declared as:
String playerName;
If that method is within Game, then you would simply have the code:
Scanner keys = new Scanner(System.in);
this.playerName = keys.nextLine();
Since you're assigning the name to a variable that exists outside the scope of the method, it will remain accessible to you later. The exact approach to this depends on how you structured your classes.
A more general solution, which could work better than the above solution depending on your code structure, would be to have that method return a String, rather than set one. For instance:
String getPlayerName() {
Scanner keys = new Scanner(System.in);
return keys.nextLine();
}
A method like that would return a string holding the name, which would allow you to work with it outside of the method.
After spending a year working with the Microsoft.Xrm.Sdk namespace, I just discovered yesterday the Entity.FormattedValues property contains the text value for Entity specific (ie Local) Option Set texts.
The reason I didn't discover it before, is there is no early bound method of getting the value. i.e. entity.new_myOptionSet is of type OptionSetValue which only contains the int value. You have to call entity.FormattedValues["new_myoptionset"] to get the string text value of the OptionSetValue.
Therefore, I'd like to get the crmsrvcutil to auto-generate a text property for local option sets. i.e. Along with Entity.new_myOptionSet being generated as it currently does, Entity.new_myOptionSetText would be generated as well.
I've looked into the Microsoft.Crm.Services.Utility.ICodeGenerationService, but that looks like it is mostly for specifying what CodeGenerationType something should be...
Is there a way supported way using CrmServiceUtil to add these properties, or am I better off writing a custom app that I can run that can generate these properties as a partial class to the auto-generated ones?
Edit - Example of the code that I would like to be generated
Currently, whenever I need to access the text value of a OptionSetValue, I use this code:
var textValue = OptionSetCache.GetText(service, entity, e => e.New_MyOptionSet);
The option set cache will use the entity.LogicalName, and the property expression to determine the name of the option set that I'm asking for. It will then query the SDK using the RetrieveAttriubteRequest, to get a list of the option set int and text values, which it then caches so it doesn't have to hit CRM again. It then looks up the int value of the New_MyOptionSet of the entity and cross references it with the cached list, to get the text value of the OptionSet.
Instead of doing all of that, I can just do this (assuming that the entity has been retrieved from the server, and not just populated client side):
var textValue = entity.FormattedValues["new_myoptionset"];
but the "new_myoptionset" is no longer early bound. I would like the early bound entity classes that gets generated to also generate an extra "Text" property for OptionSetValue properties that calls the above line, so my entity would have this added to it:
public string New_MyOptionSetText {
return this.GetFormattedAttributeValue("new_myoptionset"); // this is a protected method on the Entity class itself...
}
Could you utilize the CrmServiceUtil extension that will generate enums for your OptionSets and then add your new_myOptionSetText property to a partial class that compares the int value to the enums and returns the enum string
Again, I think specifically for this case, getting CrmSvcUtil.exe to generate the code you want is a great idea, but more generally, you can access the property name via reflection using an approach similar to the accepted answer # workarounds for nameof() operator in C#: typesafe databinding.
var textValue = entity.FormattedValues["new_myoptionset"];
// becomes
var textValue = entity.FormattedValues
[
// renamed the class from Nameof to NameOf
NameOf(Xrm.MyEntity).Property(x => x.new_MyOptionSet).ToLower()
];
The latest version of the CRM Early Bound Generator includes a Fields struct that that contains the field names. This allows accessing the FormattedValues to be as simple as this:
var textValue = entity.FormattedValues[MyEntity.Fields.new_MyOptionSet];
You could create a new property via an interface for the CrmSvcUtil, but that's a lot of work for a fairly simple call, and I don't think it justifies creating additional properties.
I'm working on a C++ Metro style app and have to pass a string by reference (somehow). At first, I passed the String^ which doesn't work because strings are immutable how I have found out.
What would be a proper way to pass a string by reference?
Edit: OK, it seems that it's not that easy since the answers and comments suggest to use return values. But as far as I think this is not applicable in my situation: In this Metro app I have two pages and a string should be "shared" across those two pages.
So in the main page I do this in a click event:
this->Frame->Navigate(newPage, this->TestString);
In the OnNavigatedTo event of the second page I convert the second parameter to a String^ and change it. Then I use this->Frame->GoBack() to navigate back to the first page. There I'd like to have access to the changed string. Unfortunately, GoBack() doesn't allow to pass any parameters as far as I know.
You can use a tracking reference:
void ModifyTheParameter(String^% value) {
value = gcnew String("Blah");
}
That would modify the original variable you passed in as parameter (see MSDN for more info and examples). It would then be used just as any other method taking a String^ parameter.
But if possible, avoid using tracking references as parameters. I'd recommend just returning a String^ and assigning that to the original variable.
Yet another possibility: You could just create some kind of View-agnostic DataModel that contains your String (and possibly other data that you work with). You could then pass that DataModel to your method. Since the DataModel variable isn't changed (just a property of it), you wouldn't need to pass a reference to it.
See below an example of a function f which takes as a parameter a reference to a std::string.
std::string someString;
void f(std::string& s);
f(someString);
This is what I am trying to do:
public void method(int myVal, string myOtherVal)
{
// doing something
}
dynamic myVar = new SomeDynamicObjectImplementer();
method(myVar.IntProperty, myVar.StringProperty);
Note that my properties are also DynamicObjects. My problem is that the TryConvert method is never called and that I get a runtime error saying the method signature is invalid.
The following is working great:
string strVar = myVar.StringProperty;
int intVar = myVar.IntProperty;
And I would like to avoid
method((int)myVar.IntProperty, (string)myVar.StringProperty);
Is it possible to override something in DynamicObject to allow this? (or something else)
Thank you
The problem is your assumption that it will try a dynamic implicit convert on arguments of an dynamic invocation to make a method call work, this is not true.
When your arguments aren't statically typed, it will use the runtime type to find the best matching method (if the runtime type matches the static rules for implicit conversion to the argument type this will work too), since your your IntProperty,StringProperty seem to be returning a DynamicObject rather than an Int and a String or something that could statically be converter implicitly, this lookup will fail.
If SomeDynamicObjectImplementer could actually return an Int for IntProperty and a String for StringProperty your method call for without casting would actually work. It's also probably a better dynamic typing practice if you data type is based on the actually type of data rather than usage using try convert. You could add actually implicit convert methods for every possible type that you could return to that returned DynamicObject type, but that could cause strange resolution issues to depending on how much you are overloading.
However, another option to keep your dynamic implementation the same is to mix a little controlled static typing in, you can use ImpromputInterface (in nuget) to put an interface on top of a dynamic object, if you do that then the TryConvert method would be called on your returned DynamicObjects.
public interface ISomeStaticInterface{
int IntProperty {get;}
string StringProperty {get;}
}
...
var myVar = new SomeDynamicObjectImplementer().ActLike<ISomeStaticInterface>();
method(myVar.IntProperty, myVar.StringProperty);
Instead of using myVar.IntProperty can't you just put them in variables first, like you already did, and then use then for your method?
so method(intVar , strVar); seems fine. At least more elegant than casting.
Of course, if you're already certain your object will have IntProperty and StringProperty, why not just make an actual object with those properties instead?
Why are you doing the cast?
method(myVar.IntProperty, myVar.StringProperty);
should compile.
If the two properties must be the types suggested by the names then they shouldn't be dynamic.