In Xamarin Forms MVVM projects, I've seen both:
public ICommand MyCommand {...}
and
public Command MyCommand {...}
What is the difference between the two, and when should I use which? Could I replace all ICommand's with Command's with no ill effect?
What is the difference between the two, and when should I use which?
They both basically provide the same functionality. The first one ICommand allows for more custom implementations of the interface while the second defines an ICommand implementation that wraps a Action. It forces the implementations to have at least a base of Command and also provides a starting point if you don't want to roll your own implementation of ICommand.
Could I replace all ICommand's with Command's with no ill effect?
The framework is happy once what you use inherits from ICommand.
ICommand command = new Command (() => Debug.WriteLine ("Command executed"));
var button = new Button {
Text = "Hit me to execute the command",
Command = command,
};
Related
So, I have bound the CombatController to an object called "godObject". In the Start() method, I call init() functions on other classes. I did this so I can control the order in which objects are initialized since, for example, the character controller relies on the grid controller being initialized.
Quick diagram:
-------------------- calls
| CombatController | ----------> CameraController.init();
-------------------- |
| ---> GridController.init();
|
| ---> CharacterController.init();
So, now I have a slight problem. I have multiple properties that I need in every controller. At the moment, I have bound everything to the combat controller itself. That means that, in every controller, I have to get an instance of the CombatController via GameObject.Find("godObject).GetComponent<CombatController>(). To be honest, I don't think this is good design.
My idea now was to create a BaseCombatController that extends MonoBehavior, and then have all other classes like GridController, CharacterController etc. extend the BaseCombatController. It might look like this:
public class BaseCombatController : MonoBehaviour
{
public GameObject activePlayer;
public void setActivePlayer(GameObject player) {
this.activePlayer = player;
}
... more stuff to come ...
}
This way, I could access activePlayer everywhere without the need to create a new instance of the CombatController. However, I'm not sure if this doesn't have possible side effects.
So, lots of text for a simple question, is that safe to do?
I use inheritance in Unity all the time. The trick, like you have in the question, is to allow your base class to inherit from monobehavior. For Example:
public class Base Item : Monobehavior
{
public string ItemName;
public int Price;
public virtual void PickUp(){//pickup logic}
//Additional functions. Update etc. Make them virtual.
}
This class sets up what an item should do. Then in a derived class you can change and extend this behavior.
public class Coin : BaseItem
{
//properties set in the inspector
public override void PickUp(){//override pickup logic}
}
I have used this design pattern a lot over the past year, and am currently using it in a retail product. I would say go for it! Unity seems to favor components over inheritance, but you could easily use them in conjunction with each other.
Hope this helps!
As far as I can see this should be safe. If you look into Unity intern or even Microsoft scripts they all extend/inhert (from) each other.
Another thing you could try would be the use of interfaces, here is the Unity Documentation to them: https://unity3d.com/learn/tutorials/topics/scripting/interfaces if you want to check it out.
You are right that GameObject.Find is pure code smell.
You can do it via the inheritance tree (as discussed earlier) or even better via interfaces (as mentioned by Assasin Bot), or (I am surprised no one mentioned it earlier) via static fields (aka the Singleton pattern).
One thing to add from experience - having to have Inits() called in a specific order is a yellow flag for your design - I've been there myself and found myself drowned by init order management.
As a general advice: Unity gives you two usefull callbacks - Awake() and Start(). If you find yourself needing Init() you are probably not using those two as they were designed.
All the Awakes() are guaranteed (for acvie objects) to run before first Start(), so do all the internal object initialisation in Awake(), and binding to external objects on Start(). If you find yourself needing finer control - you should probably simplify the design a bit.
As a rule of thumb: all objects should have their internal state (getcomponents<>, list inits etc) in order by the end of Awake(), but they shold not make any calls depending on other objects being ready before Start(). Splitting it this way usually helps a lot
I'm trying to get dependencies set up correctly in my Workflow application. It seems the best way to do this is using the Service Locator pattern that is provided by Workflow's WorkflowExtensions.
My workflow uses two repositories: IAssetRepository and ISenderRepository. Both have implementations using Entity Framework: EFAssetRepository, and EFSenderRepository, but I'd like both to use the same DbContext.
I'm having trouble getting both to use the same DbContext. I'm used to using IoC for dependency injection, so I thought I'd have to inject the DbContext into the EF repositories via their constructor, but this seems like it would be mixing the service locator and IoC pattern, and I couldn't find an easy way to achieve it, so I don't think this is the way forward.
I guess I need to chain the service locator calls? So that the constructor of my EF repositories do something like this:
public class EFAssetRepository
{
private MyEntities entities;
public EFAssetRepository()
{
this.entities = ActivityContext.GetExtension<MyEntities>();
}
}
Obviously the above won't work because the reference to ActivityContext is made up.
How can I achieve some form of dependency chain using the service locator pattern provided for WF?
Thanks,
Nick
EDIT
I've posted a workaround for my issue below, but I'm still not happy with it. I want the code activity to be able to call metadata.Require<>(), because it should be ignorant of how extensions are loaded, it should just expect that they are. As it is, my metadata.Require<> call will stop the workflow because the extension appears to not be loaded.
It seems one way to do this is by implementing IWorkflowInstanceExtension on an extension class, to turn it into a sort of composite extension. Using this method, I can solve my problem thus:
public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
private MyEntities entities = new MyEntities();
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
}
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }
public void SaveChanges()
{
this.entities.SaveChanges();
}
}
The biggest downside to doing it this way is that you can't call metadata.RequireExtension<IAssetRepository>() or metadata.RequireExtension<ISenderRepository>() in the CacheMetadata method of a CodeActivity, which is common practice. Instead, you must call metadata.RequireExtension<IUnitOfWork>(), but it is still fine to do context.GetExtension<IAssetRepository>() in the Execute() method of the CodeActivity. I imagine this is because the CacheMetadata method is called before any workflow instances are created, and if no workflow instances are created, the extension factory won't have been called, and therefore the additional extensions won't have been loaded into the WorkflowInstanceExtensionManager, so essentially, it won't know about the additional extensions until a workflow instance is created.
Does anyone know if the INotifyPropertyChanged interface can be implemented on an object in Powershell natively, without building a C# class and using Add-Type to generate a new .NET assembly?
I've Googled everything I can think of and haven't been able to find a solution.
Thanks.
I was experimenting using Powershell to load my WPF prototypes, and faced the same situation, so far I found that the solution is very simple it consists of adding interface methods to the powershell class, the last thing to deal with was the CanExecuteChanged event, through the exception message it says the method add_CanExecuteChanged wasnt found, and the solution is simply to add both the event adder and remover, for e
class Relay: System.Windows.Input.ICommand {
[Action[object]]$command;
Relay([Action[object]]$Command){
$this.command = $Command;
}
[void]add_CanExecuteChanged ([System.EventHandler]$handler){}
[void]remove_CanExecuteChanged ([System.EventHandler]$handler){}
[bool]CanExecute([object]$arg) {return $true; }
[void]Execute ([object]$arg){ $this.command?.Invoke($arg); }
}
for the INotifyPropertyChanged the situation is different since it needs getters and setters, and a call to the PropertyChanged handler on setters, the properties in powershell can be implmented as fields in C# and behind the scenes powershell add get_* and set_, which is the case in the dotnet when adding properties in the ggenerated IL you found get_, set_* methods which represents the getters and setters, for example:
class Demo {
[string]$MyProperty;
}
if you do a Get-Member -Force on an instance in the result you will find (get_MyProperty, set_MyProperty) methods, but when I tried to do so "for example like in java" the methods wont execute, but however I tried the binding without these methods and it works fine, here is my gist of the experiment, with bindings working in two way mode:
https://gist.github.com/mouadcherkaoui/7b0f32d9dbefa71102acdbb07299c9bb
and here is the source I modified, the repos it self contains a lot of good scripts:
https://github.com/SammyKrosoft/PowerShell/blob/master/How-To-Load-WPF-From-XAML.ps1
Best Regards.
No. Consider PowerShell a CLI consumer language and not so much a producer language. That is you can construct and use most .NET types. However PowerShell doesn't natively provide a facility to create new .NET types much less types that implement interfaces. While you can create custom objects in PowerShell and use tricks to give those objects a type name that PowerShell understands, those tricks don't work with .NET libraries like WPF.
On my first project trying out Caliburn.Micro, I like a lot of the things :-)
One thing I miss (or havn't discovered yet) is how to separate the viewmodel and a command.
CM doesn't support ICommand, as it's way of doing things is superior. I'm sure it's true, so I would love a small push in the right direction to achieve this or perhaps discover a better way.
As I understand you have to put the "Execute" method and "CanExecute" property directly in the viewmodel, named to match the control in the view, to get the magic to work.
I would like to put the "Execute" and "CanExecute" in a different object that is property on the viewmodel and then CM would automatically bind to that object, using the control name and property names as usually.
Repost from the forum on Caliburn Micro, I didn't get any answers so I'm trying my luck here.
You should try to avoid invalidating the Law of Demeter. Therefore, on your view model you can have an execute method, and a CanExecute property (usually calculated), and these can call into the containing model where appropriate, e.g:
public void Save
{
// .. save logic
}
public bool CanSave
{
get
{
return this.model.CanSave ... and other logic etc.
}
}
You must remember to notify a change in the calculated property when the can save state changes, e.g:
public void CodeThatGetsRunWhenAPropertyOfTheModelChanges()
{
this.NotifyOfPropertyChanged(() => this.CanSave);
}
If you have e.g. a Button on your view with x:Name="Save", then Caliburn.Micro will automatically invoke your Save verb on the view model when the button is clicked, and will automatically enable and disable the button when the CanSave property value changes.
To avoid fat ViewModels you also need to avoid fat Views. Caliburn.Micro allows you to compose Views/ViewModels as described in Screens, Conductors and Composition.
The short version is, you can include a "DetailView" and "DetailViewModel" pair in a "MasterView"/"MasterViewModel" shell by defining a DetailViewModel-typed property in MasterViewModel and adding a ContentControl named after it in MasterView. Binding and actions work as usual, so you avoid both fat models/views and routing of commands.
Another option is to bind a MasterView element to a DetailViewModel property or action, by prepending the detail's property to the target's name. I can't find the specific URL yet, so the example is from memory.
Assuming you have the following classes:
public class MasterViewModel:Screen
{
public property DetailViewModel MyDetails{get;set;}
}
and
public class DetailViewModel:Screen
{
public property string SomeText{get;set;}
public void DoTheBoogie(){}
}
You can add a control in you MasterView named 'MyDetails_SomeText' to bind to the DetailViewModel.SomeText. You can also bind to DoTheBoogie the same way.
I prefer to create a separate View though, named DetailView and add a ContentControl named "MyDetails" in MasterView. This results in a cleaner and more modular design
i'm playing with MEF and in the example i see this code ( i call it the MEF compose code):
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts();
In most examples this is done in the same source file as the Startup Program class lives, as well as all of the other interfaces and classes.
Now i want to use the MEF, but i wonder what this container does. As far as i guessed it does the export / import mapping, but what if i have this code (from a windows forms app:
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
and in that Form1 i want to create an object of type Auditer (which has a property of type ILogger marked import, and i have a class implementing ILogger marked export).
Do i have to place the MEF compose code in the void Main(), in the Load event of Form1, or in the constructor of the Auditer class?
I only get it to work when i put it (the MEF compose code) in the constructor of the Auditer class, but the examples i read somehow give me the idea that you only have to call the compose code once.
The CompositionContainer is the class that actually composes your parts in MEF.
When you want to use MEF, you need to always compose the part that's attributed with the import definitions. If you have a property in Form1 that's marked with [Import(typeof(ILogger))], at some point, you'll need to compose your Form1 instance.
The CompositionContainer is the class that actually performs this composition. It finds the appropriate exported ILogger based off the Catalog(s) contained within the container, and constructs types, matches exports to the imports, etc.
The reason that the MEF samples only "compose" one time is that, often, with DI, you'll have a single instance of the container constructed and setup at the beginning of the application, and it will compose your "main" window. All other classes will be composed automatically if they're being used as part of the main window. (For example, if Form1 composes an ILogger, but your ILogger implementation has an [Import] of it's own, it too will get composed in that pass.)
That being said, there is no fixed rule that specifies you can't compose more than once. In WPF and Silverlight, for example, it's frequent that MEF can't construct your object, which means it can't automatically compose your object for you. In these situations, a common pattern is to use the CompositionInitializer (in the box in Silverlight, not in the desktop) to have parts compose themselves, based off a static catalog. I recently blogged about this approach for WPF.
With Windows Forms, this may be less necessary, since there isn't a third party product (the XAML parser) constructing your types. However, you could still use this same approach, if you so choose.