setting command in the model for the list view - xamarin.forms

I am setting command in my model as follow
Settings test = new Settings();
private Command _navigate;
public Command Navigate
{
set { SetProperty(ref _navigate, value); }
get { return _navigate; }
}
then I am adding it to my collection
private void LoadGeneralSetting()
{
foreach ( var setting in _customSettings.GeneralSettings )
{
var detail = new Settings()
{
Type = setting.Type,
Index = setting.Index,
IsSelected = setting.Value,
Navigate = new Command(GeneralSettingNavigation(null))
};
GeneralSetting.Add(detail);
}
}
and then the method
private void GeneralSettingNavigation(object sender)
{
Application.Current.MainPage.Navigation.PushAsync(new ThemeSelection());
}
however I am getting underline "Cannot resolve constructor 'Command(void)', candidates are: Command(System.Action) (in class Command) Command(System.Action) (in class Command)"
can you please advise what am I doing wrong I have tried null setting object.. just a string but still the same outcome

that's because the constructor for Command requires an Action, just like the error message is telling you
Navigate = new Command(() => { GeneralSettingNavigation(null); })

Related

Using one session per request, how to handle updating child objects

I'm having some serious issues with Fluent Nhibernate in my ASP.NET WebForms app when trying to modify a child object and then saving the parent object.
My solution is currently made of 2 projects :
Core : A class library where all entities & repositories classes are located
Website : The ASP.NET 4.5 WebForms application
Here is my simple mapping for my Employee object:
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.DateCreated);
Map(x => x.Username);
Map(x => x.FirstName);
Map(x => x.LastName);
HasMany(x => x.TimeEntries).Inverse().Cascade.All().KeyColumn("Employee_id");
}
}
Here is my my mapping for the TimeEntry object:
public class TimeEntryMap : ClassMap<TimeEntry>
{
public TimeEntryMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.DateCreated);
Map(x => x.Date);
Map(x => x.Length);
References(x => x.Employee).Column("Employee_id").Not.Nullable();
}
}
As stated in the title, i'm using one session per request in my web app, using this code in Gobal.asax:
public static ISessionFactory SessionFactory = Core.SessionFactoryManager.CreateSessionFactory();
public static ISession CurrentSession
{
get { return (ISession)HttpContext.Current.Items["current.session"]; }
set { HttpContext.Current.Items["current.session"] = value; }
}
protected Global()
{
BeginRequest += delegate
{
System.Diagnostics.Debug.WriteLine("New Session");
CurrentSession = SessionFactory.OpenSession();
};
EndRequest += delegate
{
if (CurrentSession != null)
CurrentSession.Dispose();
};
}
Also, here is my SessionFactoryManager class:
public class SessionFactoryManager
{
public static ISession CurrentSession;
public static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("Website.Properties.Settings.WebSiteConnString")))
.Mappings(m => m
.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
.ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))
.BuildSessionFactory();
}
public static ISession GetSession()
{
return (ISession)HttpContext.Current.Items["current.session"];
}
}
Here is one of my repository class, the one i use to handle the Employee's object data operations:
public class EmployeeRepository<T> : IRepository<T> where T : Employee
{
private readonly ISession _session;
public EmployeeRepository(ISession session)
{
_session = session;
}
public T GetById(int id)
{
T result = null;
using (ITransaction tx = _session.BeginTransaction())
{
result = _session.Get<T>(id);
tx.Commit();
}
return result;
}
public IList<T> GetAll()
{
IList<T> result = null;
using (ITransaction tx = _session.BeginTransaction())
{
result = _session.Query<T>().ToList();
tx.Commit();
}
return result;
}
public bool Save(T item)
{
var result = false;
using (ITransaction tx = _session.BeginTransaction())
{
_session.SaveOrUpdate(item);
tx.Commit();
result = true;
}
return result;
}
public bool Delete(T item)
{
var result = false;
using (ITransaction tx = _session.BeginTransaction())
{
_session.Delete(_session.Load(typeof (T), item.Id));
tx.Commit();
result = true;
}
return result;
}
public int Count()
{
var result = 0;
using (ITransaction tx = _session.BeginTransaction())
{
result = _session.Query<T>().Count();
tx.Commit();
}
return result;
}
}
Now, here is my problem. When i'm trying to insert Employee(s), everything is fine. Updating is also perfect... well, as long as i'm not updating one of the TimeEntry object referenced in the "TimeEntries" property of Employee...
Here is where an exception is raised (in a ASPX file of the web project):
var emp = new Employee(1);
foreach (var timeEntry in emp.TimeEntries)
{
timeEntry.Length += 1;
}
emp.Save();
Here is the exception that is raised:
[NonUniqueObjectException: a different object with the same identifier
value was already associated with the session: 1, of entity:
Core.Entities.Employee]
Basically, whenever I try to
Load an employee and
Modify one of the saved TimeEntry, I get that exception.
FYI, I tried replacing the SaveOrUpdate() in the repository for Merge(). It did an excellent job, but when creating an object using Merge(), my object never gets it's Id set.
I also tried creating and flushing the ISession in each function of my repository. It made no sense because as soon as i was trying to load the TimeEntries property of an Employee, an exception was raised, saying the object could not be lazy-loaded as the ISession was closed...
I'm at lost and would appreciate some help. Any suggestion for my repository is also welcome, as i'm quite new to this.
Thanks you guys!
This code
var emp = new Employee(1);
foreach (var timeEntry in emp.TimeEntries)
{
timeEntry.Length += 1;
}
emp.Save();
is creating a new Employee object, presumable with an ID of 1 passed through the constructor. You should be loading the Employee from the database, and your Employee object should not allow the ID to be set since you are using an identity column. Also, a new Employee would not have any TimeEntries and the error message clearly points to an Employee instance as the problem.
I'm not a fan of transactions inside repositories and I'm really not a fan of generic repositories. Why is your EmployeeRepository a generic? Shouldn't it be
public class EmployeeRepository : IRepository<Employee>
I think your code should look something like:
var repository = new EmployeeRepository(session);
var emp = repository.GetById(1);
foreach (var timeEntry in emp.TimeEntries)
{
timeEntry.Length += 1;
}
repository.Save(emp);
Personally I prefer to work directly with the ISession:
using (var txn = _session.BeginTransaction())
{
var emp = _session.Get<Employee>(1);
foreach (var timeEntry in emp.TimeEntries)
{
timeEntry.Length += 1;
}
txn.Commit();
}
This StackOverflow Answer gives an excellent description of using merge.
But...
I believe that you are facing issues with setting up a correct session pattern for your application.
I you suggest to take a look at session-per-request pattern
where in you create a single NHibernate session object per request. the session is opened when the request is received and closed/flushed on generating a response.
Also make sure that instead of using SessionFactory.OpenSession() to get a session try using SessionFactory.GetCurrentSession() which puts the onus on NHibernate to return you the current correct session.
I hope this pushes you in the right direction.

AutoFixture: mock methods don't return a frozen instance

I'm trying to write this simple test:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var postProcessingAction = fixture.Freeze<Mock<IPostProcessingAction>>();
var postProcessor = fixture.Freeze<PostProcessor>();
postProcessor.Process("", "");
postProcessingAction.Verify(action => action.Do());
The Verify check fails.
The code for postProcessor.Process is
public void Process(string resultFilePath, string jobId)
{
IPostProcessingAction postProcessingAction =
postProcessingActionReader
.CreatePostProcessingActionFromJobResultXml(resultFilePath);
postProcessingAction.Do();
}
postProcessingActionReader is an interface field initialized through the constructor.
I'm expecting the test to pass but it fails, it turns out the instance of IPostProessingAction returned from the CreatePostProcessingActionFromJobResultXml method is not the same instance as returned from fixture.Freeze<>.
My expectation was that after freezing this Mock object it would inject the underlying mock of the IPostProcessingAction interface in every place its required as well as make all mock methods returning IPostProcessingAction return this same object.
Is my expectation about the return value of the mock methods incorrect?
Is there a way to change this behavior so that mock methods return the same frozen instance?
You need to Freeze the IPostProcessingActionReader component.
The following test will pass:
[Fact]
public void Test()
{
var fixture = new Fixture()
.Customize(new AutoMoqCustomization());
var postProcessingActionMock = new Mock<IPostProcessingAction>();
var postProcessingActionReaderMock = fixture
.Freeze<Mock<IPostProcessingActionReader>>();
postProcessingActionReaderMock
.Setup(x => x.CreatePostProcessingActionFromJobResultXml(
It.IsAny<string>()))
.Returns(postProcessingActionMock.Object);
var postProcessor = fixture.CreateAnonymous<PostProcessor>();
postProcessor.Process("", "");
postProcessingActionMock.Verify(action => action.Do());
}
Assuming that the types are defined as:
public interface IPostProcessingAction
{
void Do();
}
public class PostProcessor
{
private readonly IPostProcessingActionReader actionReader;
public PostProcessor(IPostProcessingActionReader actionReader)
{
if (actionReader == null)
throw new ArgumentNullException("actionReader");
this.actionReader = actionReader;
}
public void Process(string resultFilePath, string jobId)
{
IPostProcessingAction postProcessingAction = this.actionReader
.CreatePostProcessingActionFromJobResultXml(resultFilePath);
postProcessingAction.Do();
}
}
public interface IPostProcessingActionReader
{
IPostProcessingAction CreatePostProcessingActionFromJobResultXml(
string resultFilePath);
}
In case you use AutoFixture declaratively with the xUnit.net extension the test could be simplified even further:
[Theory, AutoMoqData]
public void Test(
[Frozen]Mock<IPostProcessingActionReader> readerMock,
Mock<IPostProcessingAction> postProcessingActionMock,
PostProcessor postProcessor)
{
readerMock
.Setup(x => x.CreatePostProcessingActionFromJobResultXml(
It.IsAny<string>()))
.Returns(postProcessingActionMock.Object);
postProcessor.Process("", "");
postProcessingActionMock.Verify(action => action.Do());
}
The AutoMoqDataAttribute is defined as:
internal class AutoMoqDataAttribute : AutoDataAttribute
{
internal AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
As of 3.20.0, you can use AutoConfiguredMoqCustomization. This will automatically configure all mocks so that their members' return values are generated by AutoFixture.
In other words, it will auto-configure your postProcessingActionReader to return the frozen postProcessingAction.
Just change this:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
to this:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());

Accessing OutArgument value of Receive implementation child activity within custom WF4 activity

Using VS2012/.NET 4.5 I am creating a custom activity which implements a Receive child activity (as an implementation child). The parameters are in the example below fixed to just one: OutValue of type Guid.
I really would love to access the value of incoming parameter value in ReceiveDone, because I need to work with it and transform it before returning it from the activity. Please ignore that I am currently using a Guid, it still fails to access the value with and InvalidOperationException:
An Activity can only get the location of arguments which it owns. Activity 'TestActivity' is trying to get the location of argument 'OutValue' which is owned by activity 'Wait for
workflow start request [Internal for TestActivity]'
I have tried everything I could think of, but am stupefied. There must be a way to do this very simple thing?
public class TestActivity : NativeActivity<Guid>
{
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
var content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
// How to access the runtime value of this inside TestActivity?
{"OutValue", new OutArgument<Guid>()}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = content
};
foreach (KeyValuePair<string, OutArgument> keyValuePair in content.Parameters)
{
metadata.AddImportedChild(keyValuePair.Value.Expression);
}
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
var receive = completedInstance.Activity as Receive;
ReceiveParametersContent content = receive.Content as ReceiveParametersContent;
try
{
// This causes InvalidOperationException.
// An Activity can only get the location of arguments which it owns.
// Activity 'TestActivity' is trying to get the location of argument 'OutValue'
// which is owned by activity 'Wait for workflow start request [Internal for TestActivity]'
var parmValue = content.Parameters["OutValue"].Get(context);
}
catch (Exception)
{ }
}
private Receive startReceiver;
private const string Namespace = "http://company.namespace";
}
Use internal variables to pass values between internal activities.
Although not directly related to your code, see the example below which should give you the idea:
public sealed class CustomNativeActivity : NativeActivity<int>
{
private Variable<int> internalVar;
private Assign<int> internalAssign;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
internalVar = new Variable<int>("intInternalVar", 10);
metadata.AddImplementationVariable(internalVar);
internalAssign = new Assign<int>
{
To = internalVar,
Value = 12345
};
metadata.AddImplementationChild(internalAssign);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(internalAssign, (activityContext, instance) =>
{
// Use internalVar value, which was seted by previous activity
var value = internalVar.Get(activityContext);
Result.Set(activityContext, value);
});
}
}
Calling the above activity:
WorkflowInvoker.Invoke<int>(new CustomNativeActivity());
Will output:
12345
Edit:
In your case your OutArgument will be the internalVar
new OutArgument<int>(internalVar);
You need to use OutArgument and them to variables. See the code example with the documentation.
I may have tried everything I thought of, but I am stubborn and refuse to give up, so I kept on thinking ;)
I here have changed my example to use a Data class as a parameter instead (it does not change anything in itself, but I needed that in my real world example).
This code below is now a working example on how to access the incoming data. The use of an implementation Variable is the key:
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
And the OutArgument:
new OutArgument<Data>(runtimeVariable)
I can then access the value with:
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
I haven't seen an example elsewhere, which does exactly this. Hope it will be of use to any one but me.
The code:
[DataContract]
public class Data
{
[DataMember]
Guid Property1 { get; set; }
[DataMember]
int Property2 { get; set; }
}
public class TestActivity : NativeActivity<Guid>
{
public ReceiveContent Content { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
{"OutValue", new OutArgument<Data> (runtimeVariable)}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = Content
};
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
}
private Receive startReceiver;
private Variable<Data> runtimeVariable;
private const string Namespace = "http://company.namespace";
}

Enable Always on Top For Caliburn Managed Window

I have the following ViewModel and I am using Caliburn Micro. The IWindowManager instance is properly resolved and all of the code works. As indicated by the TODO comment, I need to get a reference to the current window so I can toggle the AlwaysOnTop attribute. How can I do that?
namespace CaliburnWizardPlay
{
[Export(typeof(DropWindowViewModel))]
public class DropWindowViewModel : PropertyChangedBase, IHaveDisplayName
{
private readonly IWindowManager windowManager;
[ImportingConstructor]
public DropWindowViewModel(IWindowManager windowManager)
{
this.windowManager = windowManager;
}
public string DisplayName
{
get { return "Main Window"; }
set { }
}
public bool AlwaysOnTop
{
get { return Settings.Default.DropWindowAlwaysOnTop; }
set
{
Settings.Default.DropWindowAlwaysOnTop = value;
Settings.Default.Save();
NotifyOfPropertyChange(() => AlwaysOnTop);
//todo: toggle the AOT attribute of the window
}
}
public void FileDropped(DragEventArgs eventArgs)
{
if (eventArgs.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths = eventArgs.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string path in droppedFilePaths)
{
MessageBox.Show(path);
}
windowManager.ShowWindow(new WizardViewModel());
}
}
}
}
You can use the settings parameter of the ShowWindow method to set any property (e.g. Topmost) on the created window with a dictionary containing propertyname-value pairs:
windowManager.ShowWindow(new WizardViewModel(),
settings: new Dictionary<string,object> { {"Topmost", AlwaysOnTop} });
If you want to change the Topmost property of the already created window I see three options (in the order of preference):
Create an AlwaysOnTop property on the WizardViewModel and store the viewmodel in a private field and delegate the AlwaysOnTop to the WizardViewModel:
private WizardViewModel wizardViewModel;
public void FileDropped(DragEventArgs eventArgs)
{
//...
wizardViewModel = new WizardViewModel()
windowManager.ShowWindow(wizardViewModel);
}
public bool AlwaysOnTop
{
get { return Settings.Default.DropWindowAlwaysOnTop; }
set
{
//...
if (wizardViewModel != null)
wizardViewModel.AlwaysOnTop = value;
}
}
And in your view you can bind the WizardViewModel's AlwaysOnTop property to the window's TopMost property.
You can use the Application.Windows to retrieve the window. E.g. set the Name property of the created Window with the settings dictionary and then:
windowManager.ShowWindow(new WizardViewModel(),
settings: new Dictionary<string,object>
{ {"Topmost", AlwaysOnTop}, {"Name", "WizardWindow"} });
public bool AlwaysOnTop
{
get { return Settings.Default.DropWindowAlwaysOnTop; }
set
{
//...
var wizardViewModel = Application.Current.Windows.OfType<Window>()
.SingleOrDefault(w => w.Name == "WizardWindow");
if (wizardViewModel != null)
wizardViewModel.AlwaysOnTop = value;
}
}
Derive from the WindowManager and register it in your Bootstrapper and then you can override the CreateWindow, EnsureWindow etc. methods to store the created windows somewhere set the additional properties etc.

Can I get a series of good results and a thrown exception from Moq

I am mocking a wrapper to an MSMQ. The wrapper simply allows an object instance to be created that directly calls static methods of the MessageQueue class.
I want to test reading the queue to exhaustion. To do this I would like the mocked wrapper to return some good results and throw an exception on the fourth call to the same method. The method accepts no parameters and returns a standard message object.
Can I set up this series of expectations on the method in Moq?
Yup, this is possible if you don't mind jumping through a few minor hoops. I've done this for one of my projects before. Alright here is the basic technique. I just tested it out in Visual Studio 2008, and this works:
var mockMessage1 = new Mock<IMessage>();
var mockMessage2 = new Mock<IMessage>();
var mockMessage3 = new Mock<IMessage>();
var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object });
var mockMsmqWrapper = new Mock<IMsmqWrapper>();
mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() =>
{
if (messageQueue.Count == 0)
mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<MyCustomException>();
});
A few notes:
You don't have to return mocked messages, but it's useful if you want to verify expectations on each message as well to see if certain methods were called or properties were set.
The queue idea is not my own, just a tip I got from a blog post.
The reason why I am throwing an exception of MyCustomException is because the Queue class automatically throws a InvalidOperationException. I wanted to make sure that the mocked MsmqWrapper object throws an exception because of Moq and not because of the queue running out of items.
Here's the complete code that works. Keep in mind that this code is ugly in some places, but I just wanted to show you how this could be tested:
public interface IMsmqWrapper
{
IMessage GetMessage();
}
public class MsmqWrapper : IMsmqWrapper
{
public IMessage GetMessage()
{
throw new NotImplementedException();
}
}
public class Processor
{
private IMsmqWrapper _wrapper;
public int MessagesProcessed { get; set; }
public bool ExceptionThrown { get; set; }
public Processor(IMsmqWrapper msmqWrapper)
{
_wrapper = msmqWrapper;
}
public virtual void ProcessMessages()
{
_wrapper.GetMessage();
MessagesProcessed++;
_wrapper.GetMessage();
MessagesProcessed++;
_wrapper.GetMessage();
MessagesProcessed++;
try
{
_wrapper.GetMessage();
}
catch (MyCustomException)
{
ExceptionThrown = true;
}
}
}
[Test]
public void TestMessageQueueGetsExhausted()
{
var mockMessage1 = new Mock<IMessage>();
var mockMessage2 = new Mock<IMessage>();
var mockMessage3 = new Mock<IMessage>();
var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object });
var mockMsmqWrapper = new Mock<IMsmqWrapper>();
mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() =>
{
if (messageQueue.Count == 0)
mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<InvalidProgramException>();
});
var processor = new Processor(mockMsmqWrapper.Object);
processor.ProcessMessages();
Assert.That(processor.MessagesProcessed, Is.EqualTo(3));
Assert.That(processor.ExceptionThrown, Is.EqualTo(true));
}

Resources