Sequence with CodeActivities with WorkflowInvoker's input arguments doesn't work? - workflow-foundation-4

Why is it not possible to pass the arguments to CodeActivity via WorkflowInvoker's input dictionary, if the activities are within a Sequence? The WorkflowInvoker.Invoke(sequence, dict) method throws the following exception:
Additional information: The values provided for the root activity's arguments did not satisfy the root activity's requirements:
'Sequence': The following keys from the input dictionary do not map to arguments and must be removed: Arg. Please note that argument names are case sensitive.
class Program
{
static void Main(string[] args)
{
var sequence = new Sequence();
var start = new Start();
var end = new End();
sequence.Activities.Add(start);
sequence.Activities.Add(end);
var dict = new Dictionary();
dict["Arg"] = "Debug text.";
WorkflowInvoker.Invoke(sequence, dict);
}
}
public class Start : CodeActivity
{
public InArgument Arg { get; set; }
protected override void Execute(CodeActivityContext context)
{
Debug.WriteLine(Arg.Get(context));
}
}
public class End : CodeActivity
{
public InArgument Arg { get; set; }
protected override void Execute(CodeActivityContext context)
{
Debug.WriteLine(Arg.Get(context));
}
}
// ************** Second example with custom sequence *************************
class Program
{
static void Main(string[] args)
{
var seq = new MySequence();
seq.Activities.Add(new Last());
seq.Activities.Add(new First());
var dict = new Dictionary();
dict["Arg"] = "Text";
WorkflowInvoker.Invoke(seq, dict);
}
}
public class First : CodeActivity
{
public InArgument Arg { get; set; }
protected override void Execute(CodeActivityContext context)
{
var val = Arg.Get(context);
}
}
public class Last : CodeActivity
{
public InArgument Arg { get; set; }
protected override void Execute(CodeActivityContext context)
{
var val = Arg.Get(context);
}
}
public class MySequence : NativeActivity
{
public InArgument Arg { get; set; }
public Collection Activities = new Collection();
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.SetChildrenCollection(Activities);
}
protected override void Execute(NativeActivityContext context)
{
foreach (var activity in Activities)
context.ScheduleActivity(activity);
}
}

The code activities take their arguments from the container they are in not the input dictionary. The container needs to have an in argument matching the one in the dictionary.
Sequences don't accept arguments so you wrap them in an Activity.
An Activity constructed as below is a worklfow
public class MyCodeWorkflow : Activity
{
public InArgument<string> inMSG { get; set; }
public OutArgument<string> outMSG { get; set; }
public MyCodeWorkflow()
{
this.Implementation = () => new Sequence {
Activities =
{
new WriteLine
{
Text=new InArgument<string>((activityContext)=>this.inMSG.Get(activityContext))
},
new Assign<string>
{
To=new ArgumentReference<string>("outMSG"),
Value=new InArgument<string>
(
(activityContext)=>this.inMSG.Get(activityContext)
)
}
}
};
}
}
//host
static void Main(string[] args)
{
IDictionary<string, object> input = new Dictionary<string, object>();
input.Add("inMSG","hello");
IDictionary<string, object> output = new Dictionary<string, object>();
MyCodeWorkflow activity = new MyCodeWorkflow();
output = WorkflowInvoker.Invoke(activity,input);
Console.WriteLine(output["outMSG"]);
}
The code above was taken from http://xhinker.com/post/WF4Authoring-WF4-using-imperative-code%28II%29.aspx

Related

unit text mock dbContext

I try to do a unitary test on a repository that returns a Ienumerable. But I have the next mistake:
System.AggregateException : One or more errors occurred. (The source IQueryable doesn't implement IAsyncEnumerable<myNamespace.DTO.UserDTO>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.)
---- System.InvalidOperationException : The source IQueryable doesn't implement IAsyncEnumerable<myNamespace.DTO.UserDTO>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
This my unit test :
//Arrange
var mockSet = Substitute.For<DbSet<User>, IQueryable<User>, IDbAsyncEnumerable<User>>();
((IDbAsyncEnumerable<User>)mockSet).GetAsyncEnumerator()
.Returns(new TestDbAsyncEnumerator<User>(GetUserList().AsQueryable().GetEnumerator()));
((IQueryable<User>)mockSet).Provider.Returns(new TestDbAsyncQueryProvider<User>(GetUserList().AsQueryable().Provider));
((IQueryable<User>)mockSet).Expression.Returns(GetUserList().AsQueryable().Expression);
((IQueryable<User>)mockSet).ElementType.Returns(GetUserList().AsQueryable().ElementType);
((IQueryable<User>)mockSet).GetEnumerator().Returns(GetUserList().AsQueryable().GetEnumerator());
var mockContext = Substitute.For<IMyContext>();
mockContext.Users.Returns(mockSet);
//Act
CancellationToken cancellationToken = new CancellationToken();
UserRepository userRepository = new UserRepository(mockContext);
var users = userRepository.GetListAsync(cancellationToken).Result;
//Assert
Assert.NotNull(users);
My repo I want to test :
public async Task<IEnumerable<UserDto>> GetListAsync(CancellationToken cancellationToken)
{
return await _myContext.Users.Select(u => new UserDto
{
Id = u.Id,
FistName = u.FistName ,
LastName = u.LastName
}).ToListAsync(cancellationToken);
}
What is the problem ?
As covered in the OP comments the doco you're referring to is for EF, not EFCore. You need to implement a different set of interfaces.
The usual advice is to avoid mocking the DbContext however in this case you probably need to as the async operations aren't supported by the in-memory provider. I'm not sure if SQLite supports them. EntityFrameworkCore.Testing should handle this case (disclaimer, I am the author), but you'd need to use your context implementation rather than an interface.
The most common way to get this working is to create implementations of the async interfaces, in the same manner as the EF doco but for EFCore. You'll find most EFCore mocking libraries will do it this way:
public class TestAsyncEnumerable<T> : IAsyncEnumerable<T>, IOrderedQueryable<T>
{
private readonly IEnumerable<T> _enumerable;
private readonly IQueryable<T> _queryable;
public TestAsyncEnumerable(IEnumerable<T> enumerable)
{
_enumerable = enumerable;
_queryable = _enumerable.AsQueryable();
ElementType = _queryable.ElementType;
Expression = _queryable.Expression;
Provider = new TestAsyncQueryProvider<T>(_queryable);
}
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken())
{
return new TestAsyncEnumerator<T>(_queryable);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
public Type ElementType { get; }
public Expression Expression { get; }
public IQueryProvider Provider { get; }
}
public class TestAsyncEnumerator<T> : IAsyncEnumerator<T>
{
private readonly IEnumerator<T> _enumerator;
public TestAsyncEnumerator(IEnumerable<T> enumerable)
{
_enumerator = enumerable.GetEnumerator();
}
public ValueTask DisposeAsync()
{
return new ValueTask();
}
public ValueTask<bool> MoveNextAsync()
{
return new ValueTask<bool>(_enumerator.MoveNext());
}
public T Current => _enumerator.Current;
}
public class TestAsyncQueryProvider<T> : IAsyncQueryProvider
{
public TestAsyncQueryProvider(IQueryable<T> source)
{
Source = source;
}
private IQueryable<T> Source { get; }
public IQueryable CreateQuery(Expression expression)
{
throw new NotImplementedException();
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new TestAsyncEnumerable<TElement>(Source.Provider.CreateQuery<TElement>(expression));
}
public object Execute(Expression expression)
{
throw new NotImplementedException();
}
public TResult Execute<TResult>(Expression expression)
{
throw new NotImplementedException();
}
public TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}
}
This isn't a complete implementation, just what's needed to solve the OP case. The important bit is this line:
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new TestAsyncEnumerable<TElement>(Source.Provider.CreateQuery<TElement>(expression));
}
This is what is going to allow the projection to work with the async operation.
Working example:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using AutoFixture;
using KellermanSoftware.CompareNetObjects;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
using NSubstitute;
using NUnit.Framework;
namespace Question62783423
{
public class Tests
{
[Test]
public void Test1()
{
var fixture = new Fixture();
var users = new TestAsyncEnumerable<User>(fixture.CreateMany<User>());
//Arrange
var mockSet = Substitute.For<DbSet<User>, IQueryable<User>, IAsyncEnumerable<User>>();
((IAsyncEnumerable<User>) mockSet).GetAsyncEnumerator().Returns(users.GetAsyncEnumerator());
((IQueryable<User>) mockSet).Provider.Returns(users.Provider);
((IQueryable<User>) mockSet).Expression.Returns(users.Expression);
((IQueryable<User>) mockSet).ElementType.Returns(users.ElementType);
((IQueryable<User>) mockSet).GetEnumerator().Returns(((IQueryable<User>) users).GetEnumerator());
var mockContext = Substitute.For<IMyContext>();
mockContext.Users.Returns(mockSet);
//Act
var cancellationToken = new CancellationToken();
var userRepository = new UserRepository(mockContext);
var result1 = userRepository.GetListAsync(cancellationToken).Result;
var result2 = userRepository.GetListAsync(cancellationToken).Result;
var comparer = new CompareLogic();
comparer.Config.IgnoreCollectionOrder = true;
comparer.Config.IgnoreObjectTypes = true;
var comparisonResult1 = comparer.Compare(users, result1);
var comparisonResult2 = comparer.Compare(users, result2);
Assert.That(comparisonResult1.Differences.Any(), Is.False);
Assert.That(comparisonResult2.Differences.Any(), Is.False);
}
}
}
public class TestAsyncEnumerable<T> : IAsyncEnumerable<T>, IOrderedQueryable<T>
{
private readonly IEnumerable<T> _enumerable;
private readonly IQueryable<T> _queryable;
public TestAsyncEnumerable(IEnumerable<T> enumerable)
{
_enumerable = enumerable;
_queryable = _enumerable.AsQueryable();
ElementType = _queryable.ElementType;
Expression = _queryable.Expression;
Provider = new TestAsyncQueryProvider<T>(_queryable);
}
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken())
{
return new TestAsyncEnumerator<T>(_queryable);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
public Type ElementType { get; }
public Expression Expression { get; }
public IQueryProvider Provider { get; }
}
public class TestAsyncEnumerator<T> : IAsyncEnumerator<T>
{
private readonly IEnumerator<T> _enumerator;
public TestAsyncEnumerator(IEnumerable<T> enumerable)
{
_enumerator = enumerable.GetEnumerator();
}
public ValueTask DisposeAsync()
{
return new ValueTask();
}
public ValueTask<bool> MoveNextAsync()
{
return new ValueTask<bool>(_enumerator.MoveNext());
}
public T Current => _enumerator.Current;
}
public class TestAsyncQueryProvider<T> : IAsyncQueryProvider
{
public TestAsyncQueryProvider(IQueryable<T> source)
{
Source = source;
}
private IQueryable<T> Source { get; }
public IQueryable CreateQuery(Expression expression)
{
throw new NotImplementedException();
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new TestAsyncEnumerable<TElement>(Source.Provider.CreateQuery<TElement>(expression));
}
public object Execute(Expression expression)
{
throw new NotImplementedException();
}
public TResult Execute<TResult>(Expression expression)
{
throw new NotImplementedException();
}
public TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}
}
public class User
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UserDto
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IMyContext
{
DbSet<User> Users { get; set; }
}
public class UserRepository
{
private readonly IMyContext _myContext;
public UserRepository(IMyContext myContext)
{
_myContext = myContext;
}
public async Task<IEnumerable<UserDto>> GetListAsync(CancellationToken cancellationToken)
{
return await _myContext.Users.Select(u => new UserDto { Id = u.Id, FirstName = u.FirstName, LastName = u.LastName }).ToListAsync(cancellationToken);
}
}

Why my diffutils dont update my position in background

I'm using DiffUtils to update my Recyclerview.
Visually works but clicking an item returns it to me a position that does not match the item I clicked
I used NotifyDataChange that was able to solve the position problem. But visually, the last item is misconfigured.
I try to use NotifyDataChange that was able to solve the position problem. But visually, the last item is misconfigured.
My adapter:
class AdapterUser : RecyclerView.Adapter
{
//Global Var
public event EventHandler<int> ItemClick;
public List<Class.Result> ClassUser;
public Android.Content.Context context;
public class UserViewHolder : RecyclerView.ViewHolder
{
public static TextView txtName { get; set; }
public static TextView txtEspecialidade { get; set; }
public static CircleImageView Imagem { get; set; }
public static Bitmap bitmap { get; set; }
public static CircleImageView status { get; set; }
public static Button button { get; set; }
public UserViewHolder(View itemview, Action<int> listener) : base(itemview)
{
UserViewHolder.txtName = itemview.FindViewById<TextView>(Resource.Id.nameUser);
UserViewHolder.txtEspecialidade = itemview.FindViewById<TextView>(Resource.Id.speciality);
UserViewHolder.Imagem = itemview.FindViewById<CircleImageView>(Resource.Id.avatarUser);
UserViewHolder.status = itemview.FindViewById<CircleImageView>(Resource.Id.status);
UserViewHolder.button = itemview.FindViewById<Button>(Resource.Id.BtCriar);
}
}
public AdapterUser(List<Class.Result> user)
{
ClassUser = user;
}
public override int ItemCount
{
get { return ClassUser.Count(); }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
//Method to transform the uri to bitmap
async Task MyMethodAsync()
{
// Do asynchronous work.
UserViewHolder.Imagem.SetImageBitmap(await Droid.Class.Functions.GetImageBitmapFromUrlAsync(ClassUser[position].PhotoUri));
};
UserViewHolder userHolder = holder as UserViewHolder;
if (ClassUser[position].PhotoUri != null)
{
MyMethodAsync();
}
else
{
UserViewHolder.Imagem.SetImageResource(Resource.Drawable.avatar);
}
if (ClassUser[position].IsOnline != true)
{
UserViewHolder.status.Visibility = ViewStates.Invisible;
}
else
{
UserViewHolder.status.Visibility = ViewStates.Visible;
}
UserViewHolder.txtName.Text = ClassUser[position].Name;
UserViewHolder.txtEspecialidade.Text = ClassUser[position].Specialty;
UserViewHolder.button.Click += (sender, args) =>
{
Toast.MakeText(context, ClassUser[position].Name, ToastLength.Short).Show();
Console.WriteLine(ClassUser[position].Name);
};
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.ResultUser, parent, false);
UserViewHolder vh = new UserViewHolder(itemView, OnClick);
context = parent.Context;
return vh;
}
private void OnClick(int obj)
{
}
public void Update(List<Class.Result> oldList, List<Class.Result> newList)
{
// Set detectMoves to true for smoother animations
MyDiffCallback callback = new MyDiffCallback(oldList, newList);
DiffUtil.DiffResult result = DiffUtil.CalculateDiff(callback);
this.ClassUser.Clear();
this.ClassUser.AddRange(newList);
// Despatch the updates to your RecyclerAdapter
result.DispatchUpdatesTo(this);
}
My DiffUtills:
class MyDiffCallback : DiffUtil.Callback
{
List<Class.Result> newList;
List<Class.Result> oldList;
public MyDiffCallback(List<Class.Result> oldList, List<Class.Result> newList)
{
this.oldList = oldList;
this.newList = newList;
}
public override int NewListSize => newList.Count;
public override int OldListSize => oldList.Count;
public override bool AreContentsTheSame(int oldItemPosition, int newItemPosition)
{
return oldList[oldItemPosition].IsOnline == newList[newItemPosition].IsOnline;
}
public override bool AreItemsTheSame(int oldItemPosition, int newItemPosition)
{
return oldList[oldItemPosition].RowKey == newList[newItemPosition].RowKey;
}
public override Java.Lang.Object GetChangePayload(int oldItemPosition, int newItemPosition)
{
return base.GetChangePayload(oldItemPosition, newItemPosition);
}
}
My activity:
ClassUtilizador = Data.Result.ToString();
Class.ClassUtilizador classUser = JsonConvert.DeserializeObject<Class.ClassUtilizador>(Data.Result.ToString());
//Call the function to update item
adapter.Update(classUserOld.Result, classUser.Result);
//Clean class and put the new data
classUserOld = new Class.ClassUtilizador();
classUserOld = classUser;
Update items, remove, add ou move items. Depending of my request.
You should call:
holder.bindingAdapterPosition
clicking an item returns it to me a position that does not match the
item I clicked
UserViewHolder.button.Click += (sender, args) =>
{
Toast.MakeText(context, ClassUser[position].Name, ToastLength.Short).Show();
Console.WriteLine(ClassUser[position].Name);
};
change to :
UserViewHolder.button.Tag = position;
UserViewHolder.button.SetOnClickListener(this);
then let your adapter extends View.IOnClickListener
class AdapterUser : RecyclerView.Adapter,View.IOnClickListener
public void OnClick(View v)
{
//here you could get the correct position
Toast.MakeText(context, v.Tag.ToString(), ToastLength.Short).Show();
}
if it doesn't update your Recyclerview, you could add the method in your adapter:
public void setData(List<Class.Result> newList)
{
this.ClassUser= new List<Class.Result>(newList);
}
in your update method :
public void Update(List<Class.Result> oldList, List<Class.Result> newList)
{
// Set detectMoves to true for smoother animations
MyDiffCallback callback = new MyDiffCallback(oldList, newList);
DiffUtil.DiffResult result = DiffUtil.CalculateDiff(callback);
this.ClassUser.Clear();
this.ClassUser.AddRange(newList);
setData(this.ClassUser);
// Despatch the updates to your RecyclerAdapter
result.DispatchUpdatesTo(this);
}

Can not read data from firebase as List in android

I read many articles but still my problem is continuing, while fetching data from firebase as list. could you please help me on this.
Error: com.google.firebase.database.DatabaseException: Can't convert
object of type java.lang.String to type SubCategoryLoad Object
Firebase database image
--> Loading data from firebase:
mSubCategoryDatabaseRef = FirebaseDatabase.getInstance().getReference("user_post_add_database_ref").child("yeswanth599").child(mCategoryNameReceive);
mSubCategoryDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
GenericTypeIndicator<Map<String,SubCategoryLoad>> genericTypeIndicator=new GenericTypeIndicator<Map<String,SubCategoryLoad>>(){};
(-->Error Showing in this Line) Map<String,SubCategoryLoad> map=(Map<String, SubCategoryLoad>)postSnapshot.getValue(genericTypeIndicator);
assert map != null;
mSubCategoryLoad=new ArrayList<>(map.values());
}
mSubCategoryAdapter = new SubCategoryDisplayAdapter(getContext(), mSubCategoryLoad);
mSubCategoryRecyclerView.setAdapter(mSubCategoryAdapter);
mSubCategoryProgressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
mSubCategoryProgressCircle.setVisibility(View.INVISIBLE);
}
});
--> SubCategoryLoad.Class
public class SubCategoryLoad {
private String mUserPostAddress;
private String mUserPostBusinessEndTime;
private String mUserPostBusinessSelectedCity;
private String mUserPostBusinessSelectedCountry;
private String mUserPostBusinessStartTime;
private String mUserPostCategory;
private String mUserPostEmail;
private List<UserPostAdsImages> mUserPostImages;
private String mUserPostName;
private String mUserPostPhonenumber;
private List<UserPostAdsLanguages> mUserPostSupportingLanguage;
private String mUserPostWebsite;
public SubCategoryLoad() {
//empty constructor needed
}
public SubCategoryLoad(String userPostAddress, String userPostBusinessEndTime,
String userPostBusinessSelectedCity, String userPostBusinessSelectedCountry,
String userPostBusinessStartTime, String userPostCategory,
String userPostEmail, List<UserPostAdsImages> userPostImages,
String userPostName, String userPostPhonenumber,
List<UserPostAdsLanguages> userPostSupportingLanguage, String userPostWebsite
) {
mUserPostAddress = userPostAddress;
mUserPostBusinessEndTime = userPostBusinessEndTime;
mUserPostBusinessSelectedCity = userPostBusinessSelectedCity;
mUserPostBusinessSelectedCountry = userPostBusinessSelectedCountry;
mUserPostBusinessStartTime = userPostBusinessStartTime;
mUserPostCategory = userPostCategory;
mUserPostEmail = userPostEmail;
mUserPostImages = userPostImages;
mUserPostName = userPostName;
mUserPostPhonenumber = userPostPhonenumber;
mUserPostSupportingLanguage = userPostSupportingLanguage;
mUserPostWebsite = userPostWebsite;
}
public void setUserPostAddress(String userPostAddress) {
this.mUserPostAddress = userPostAddress;
}
public void setUserPostBusinessEndTime(String userPostBusinessEndTime) {
this.mUserPostBusinessEndTime = userPostBusinessEndTime;
}
public void setUserPostBusinessSelectedCity(String userPostBusinessSelectedCity) {
this.mUserPostBusinessSelectedCity = userPostBusinessSelectedCity;
}
public void setUserPostBusinessSelectedCountry(String userPostBusinessSelectedCountry) {
this.mUserPostBusinessSelectedCountry = userPostBusinessSelectedCountry;
}
public void setUserPostBusinessStartTime(String userPostBusinessStartTime) {
this.mUserPostBusinessStartTime = userPostBusinessStartTime;
}
public void setUserPostCategory(String userPostCategory) {
this.mUserPostCategory = userPostCategory;
}
public void setUserPostEmail(String userPostEmail) {
this.mUserPostEmail = userPostEmail;
}
public void setUserPostImages(List<UserPostAdsImages> userPostImages) {
this.mUserPostImages = userPostImages;
}
public void setUserPostName(String userPostName) {
this.mUserPostName = userPostName;
}
public void setUserPostPhonenumber(String userPostPhonenumber) {
this.mUserPostPhonenumber = userPostPhonenumber;
}
public void setUserPostSupportingLanguage(List<UserPostAdsLanguages> userPostSupportingLanguage) {
this.mUserPostSupportingLanguage = userPostSupportingLanguage;
}
public void setUserPostWebsite(String userPostWebsite) {
this.mUserPostWebsite = userPostWebsite;
}
public String getUserPostAddress() {
return mUserPostAddress;
}
public String getUserPostBusinessEndTime() {
return mUserPostBusinessEndTime;
}
public String getUserPostBusinessSelectedCity() {
return mUserPostBusinessSelectedCity;
}
public String getUserPostBusinessSelectedCountry() {
return mUserPostBusinessSelectedCountry;
}
public String getUserPostBusinessStartTime() {
return mUserPostBusinessStartTime;
}
public String getUserPostCategory() {
return mUserPostCategory;
}
public String getUserPostEmail() {
return mUserPostEmail;
}
public List<UserPostAdsImages> getUserPostImages() {
return mUserPostImages;
}
public String getUserPostName() {
return mUserPostName;
}
public String getUserPostPhonenumber() {
return mUserPostPhonenumber;
}
public List<UserPostAdsLanguages> getUserPostSupportingLanguage() {
return mUserPostSupportingLanguage;
}
public String getUserPostWebsite() {
return mUserPostWebsite;
}
}
--> SubCategoryDisplayAdapter.class
SubCategoryLoad subCategoryLoadCurrent = mSubCategoryLoad.get(position);
holder.mSubCategoryAdsTitle.setText(subCategoryLoadCurrent.getUserPostName());
holder.mSubCategoryAdsSupportingLanguagesList.setText("English,Japanese");
//Log.i(TAG, "message:"+subCategoryLoadCurrent.getUserPostImages().get(0).getUserPostImageList());
Glide.with(mContext)
.load(subCategoryLoadCurrent.getUserPostImages().get(0).getUserPostImageList())
.into(holder.mSubCategoryAdsImage);
Thanks & Regards,
Yeswanth.
I used to have the same issue with my parsing and the problem was instead of a list of custom objects i was supposed to be using a Map like this
private Map<String,Boolean>
That field in Firebase contains a key and a state (True or False).
Also you can check the code on the docs to see how they parse these objects.
https://firebase.google.com/docs/database/android/read-and-write?authuser=0#read_data_once

Scheduling child activity that implements an interface with input parameters

public sealed class Parent : NativeActivity
{
public Parent()
{
Childrens = new Collection<Activity>();
Variables = new Collection<Variable>();
_currentActivityIndex = new Variable<int>();
CurrentCustomTypeInstance= new Variable<MyCustomType>();
}
[Browsable(false)]
public Collection<Activity> Childrens { get; set; }
protected override void Execute(NativeActivityContext context)
{
_currentActivityIndex.Set(context, 0);
context.ScheduleActivity(FirstActivity, Callback);
}
private void Callback(NativeActivityContext context, ActivityInstance completedInstance, MyCustomType customTypeInstance)
{
CurrentCustomTypeInstance.Set(context, customTypeInstance);
ScheduleNextChildren(context, completedInstance);
}
private void ScheduleNextChildren(NativeActivityContext context, ActivityInstance completedInstance)
{
int nextActivityIndex = _currentActivityIndex.Get(context) + 1;
if (nextActivityIndex >= Childrens.Count)
return;
Activity nextActivity = Childrens[nextActivityIndex];
IFoo nextActivityAsIFoo = nextActivity as IFoo;
if (nextActivityAsIFoo != null)
{
var currentCustomTypeInstance = CurrentCustomTypeInstance.Get(context);
// HERE IS MY EXCEPTION
nextActivityAsIFoo.FooField.Set(context, currentCustomTypeInstance);
}
context.ScheduleActivity(nextActivity);
_currentActivityIndex.Set(context, nextActivityIndex);
}
}
And in register metadata:
metadata.SetChildrenCollection(Childrens);
I've already read http://msmvps.com/blogs/theproblemsolver/archive/2011/04/05/scheduling-child-activities-with-input-parameters.aspx but in my case, parent does not know the child activity
Edit
Similar to: Activity cannot set a Variable defined within its scope?
Activity '1.1: Parent' cannot access this variable because it is declared at the scope
of activity '1.1: Parent'. An activity can only access its own implementation variables.
But in my case, I don't need to get the return value, so, hope to be easier. Just need to pass FooField implicitly instead of leting it to flow author.
I need to do it implicitly! If it doesn't work at all, I will go with NativeActivityContext Properties
Got it! Looking at the Maurice's blog I got inspired to do it
Workflow(very very simple!)
static void Main(string[] args)
{
Parent parent = new Parent();
parent.Childrens.Add(new FooWriter());
parent.Childrens.Add(new FooFormater());
parent.Childrens.Add(new FooWriter());
WorkflowInvoker.Invoke(parent);
Console.Read();
}
Output
What's the Foo name?
Implicit FTW!
Im a custom Foo Handler, my Foo name is: Implicit FTW!
Im a custom Foo Handler, my Foo name is: IMPLICIT FTW!
Implementation
using System;
using System.Activities;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WorkflowConsoleApplication2
{
// Parent class that creates a Foo and passes it to their childrens
public sealed class Parent : NativeActivity
{
private Variable<int> _currentActivityIndex;
private Variable<Foo> _currentFoo;
public Parent()
{
Childrens = new Collection<Activity>();
_executionChildrens = new Collection<Tuple<Activity, ActivityAction<Foo>>>();
_currentActivityIndex = new Variable<int>();
_currentFoo = new Variable<Foo>();
}
[Browsable(false)]
public Collection<Activity> Childrens { get; set; }
private Collection<Tuple<Activity, ActivityAction<Foo>>> _executionChildrens;
protected override void Execute(NativeActivityContext context)
{
Console.WriteLine("What's the Foo name?");
_currentFoo.Set(context, new Foo { Name = Console.ReadLine() });
_currentActivityIndex.Set(context, 0);
ScheduleNextChildren(context, null);
}
private void ScheduleNextChildren(NativeActivityContext context, ActivityInstance completedInstance)
{
int currentActivityIndex = _currentActivityIndex.Get(context);
if (currentActivityIndex >= Childrens.Count)
return;
Tuple<Activity, ActivityAction<Foo>> nextActivity = _executionChildrens[currentActivityIndex];
if (IsFooHandler(nextActivity))
{
context.ScheduleAction(nextActivity.Item2, _currentFoo.Get(context),
ScheduleNextChildren);
}
else
{
context.ScheduleActivity(nextActivity.Item1,
ScheduleNextChildren);
}
_currentActivityIndex.Set(context, currentActivityIndex + 1);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetArgumentsCollection(metadata.GetArgumentsWithReflection());
metadata.AddImplementationVariable(_currentActivityIndex);
metadata.AddImplementationVariable(_currentFoo);
RegisterChildrens(metadata, Childrens);
// remove "base.Cachemetadata" to "Childrens collection" doesn't become a child again }
public void RegisterChildrens(NativeActivityMetadata metadata, IEnumerable<Activity> childrens)
{
foreach (Activity child in childrens)
{
IFooHandler childAsIFooHandler = child as IFooHandler;
if (childAsIFooHandler != null)
{
ActivityAction<Foo> childsWrapperAction = new ActivityAction<Foo>();
var activityToActionBinderArgument = new DelegateInArgument<Foo>();
childsWrapperAction.Argument = activityToActionBinderArgument;
childAsIFooHandler.Foo = activityToActionBinderArgument;
childsWrapperAction.Handler = child;
metadata.AddDelegate(childsWrapperAction);
_executionChildrens.Add(new Tuple<Activity, ActivityAction<Foo>>(child, childsWrapperAction));
}
else
{
metadata.AddChild(child);
_executionChildrens.Add(new Tuple<Activity, ActivityAction<Foo>>(child, null));
}
}
}
public static bool IsFooHandler(Tuple<Activity, ActivityAction<Foo>> activity)
{
return activity.Item2 != null;
}
}
// samples of Foo handlers
public class FooWriter : CodeActivity, IFooHandler
{
/// When FooWriter is direct child of "Parent" this argument is passed implicitly
public InArgument<Foo> Foo { get; set; }
protected override void Execute(CodeActivityContext context)
{
Console.WriteLine("Im a custom Foo Handler, my Foo name is: {0}", Foo.Get(context).Name);
}
}
public class FooFormater : CodeActivity, IFooHandler
{
public InArgument<Foo> Foo { get; set; }
protected override void Execute(CodeActivityContext context)
{
Foo foo = Foo.Get(context);
foo.Name = foo.Name.ToUpper();
}
}
// sample classes
public class Foo
{
public string Name { get; set; }
}
public interface IFooHandler
{
InArgument<Foo> Foo { get; set; }
}
}
If anyone know how to do it in a better way please fell free to tell me. I will also need to pass the values to nested activities

Create a log everytime When methods in an interface class are called

I want to update a log file(txt) everytime when methods in a an interface class are called?
Is there any way to do this other than writing code in every method to create log?
Here's my 30 mins. you'll have to implement the logging code somewhere so you have to create another abstraction for your code. thus an abstract class is needed. i think. this is very quick and dirty.
public interface IService<T>
{
List<T> GetAll();
bool Add(T obj);
}
then you'll need the abstract class where you'll need to implement your logging routine
public abstract class Service<T> : IService<T>
{
private void log()
{
/// TODO : do log routine here
}
public bool Add(T obj)
{
try
{
log();
return AddWithLogging(obj);
}
finally
{
log();
}
}
public List<T> GetAll()
{
try
{
log();
return GetAllWithLog();
}
finally
{
log();
}
}
protected abstract List<T> GetAllWithLog();
protected abstract bool AddWithLogging(T obj);
}
as for your concrete classes
public class EmployeeService : Service<Employee>
{
protected override List<Employee> GetAllWithLog()
{
return new List<Employee>() { new Employee() { Id = 0, Name = "test" } };
}
protected override bool AddWithLogging(Employee obj)
{
/// TODO : do add logic here
return true;
}
}
public class CompanyService : Service<Company>
{
protected override List<Company> GetAllWithLog()
{
return new List<Company>() { new Company() { Id = 0, Name = "test" } };
}
protected override bool AddWithLogging(Company obj)
{
/// TODO : do add logic here
return true;
}
}
public class Employee
{
public int Id {get;set;}
public string Name { get; set;}
}
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
}
then on your implementation you can just..
static void Main(string[] args)
{
IService<Employee> employee = new EmployeeService();
List<Employee> employees = employee.GetAll();
foreach (var item in employees)
{
Console.WriteLine(item.Name);
}
IService<Company> company = new CompanyService();
List<Company> companies = company.GetAll();
foreach (var item in companies)
{
Console.WriteLine(item.Name);
}
Console.ReadLine();
}
hope this helps!
I think you would have to use Aspect Oriented Programming to achieve that. Read http://www.sharpcrafters.com/aop.net
I think you meant class (instead of interface)
Two options I can think of:
Implementing INotifyPropertyChanged which is in lines of writing code in every method
or
to adopt on of the AOP frameworks in the article http://www.codeproject.com/KB/cs/AOP_Frameworks_Rating.aspx if that is not a major leap

Resources