/// <summary>
/// 依不同的 Type 決定要用那個 Class
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
[Obsolete]
public static IActionStrategy ResolveActionStrategy(BotAction botAction)
{
IActionStrategy result = null;
switch (botAction.ActionType)
{
case ActionTypes.ShowAcountAction:
result = new ShowAccountActionStrategy();
break;
case ActionTypes.AccountAction:
result = new AccountActionStrategy();
break;
case ActionTypes.ShowMenuAction:
result = new ShowMenuActionStrategy();
break;
case ActionTypes.OrderAction:
result = new OrderActionStrategy();
break;
default:
result = new NoneActionStrategy();
break;
}
return result;
}
/// <summary>
/// 設定 ACTION_TYPE 對應要建立的物件
/// </summary>
/// <param name="builder"></param>
public static void ResolveByActionTypes(ContainerBuilder builder)
{
builder
.RegisterType<ShowAccountActionStrategy>()
.Named<IActionStrategy>(ActionTypes.ShowAcountAction.ToString())
.InstancePerLifetimeScope();
builder
.RegisterType<AccountActionStrategy>()
.Named<IActionStrategy>(ActionTypes.AccountAction.ToString())
.InstancePerLifetimeScope();
builder
.RegisterType<ShowMenuActionStrategy>()
.Named<IActionStrategy>(ActionTypes.ShowMenuAction.ToString())
.InstancePerLifetimeScope();
builder
.RegisterType<OrderActionStrategy>()
.Named<IActionStrategy>(ActionTypes.OrderAction.ToString())
.InstancePerLifetimeScope();
}
/// <summary>
/// 透過 ACTION_TYPE 來建立對應的 Strategy 物件
/// </summary>
/// <param name="botAction"></param>
/// <param name="context"></param>
/// <returns></returns>
public async static Task DoActionAsync(BotAction botAction, IDialogContext context)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, context.Activity.AsMessageActivity()))
{
var actionStrategy = scope.ResolveNamed<IActionStrategy>(botAction.ActionType.ToString());
await actionStrategy.DoActionAsync(botAction, context);
//註:如果您的 strategy 有用到 PromptDialog Or Other ResumeAfter 你就不能在這裡 CALL context.Done()
if (actionStrategy.IsContextDone)
{
context.Done("");
}
}
}
// 設定依 ActionType 來建立物件的 Dictionary
static Dictionary<string, Func<JToken, BotAction>> BotActionMapper;
static ActionConverter()
{
ResolveByActionTypes();
}
/// <summary>
/// 依 ActionType 來決定要建立那個 Action 及初始化處理
/// </summary>
private static void ResolveByActionTypes()
{
Func<JToken, BotAction> acountActionFun = jtoken => new AccountAction();
Func<JToken, BotAction> orderActionFun = jtoken =>
{
var result = new OrderAction();
//建立物件後,如果還有其他要處理的事,可以接著寫下去...
//AssignProducts(result as OrderAction, jtoken as JObject);
return result;
};
BotActionMapper = new Dictionary<string, Func<JToken, BotAction>>(){
{ActionTypes.AccountAction.ToString(), acountActionFun },
{ActionTypes.OrderAction.ToString(), orderActionFun }
};
}
/// <summary>
/// 依 ActionType 來決定要轉回什麼物件
/// </summary>
/// <param name="reader"></param>
/// <param name="objectType"></param>
/// <param name="existingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jtoken = JToken.ReadFrom(reader);
var type = jtoken["ActionType"].ToObject<ActionTypes>();
BotAction result = BotActionMapper[type.ToString()](jtoken);
serializer.Populate(jtoken.CreateReader(), result);
return result;
}
/// <summary>
/// 定義 Action 共通的 interface
/// </summary>
public interface IActionStrategy
{
Task DoActionAsync(BotAction botAction, IDialogContext context);
bool IsContextDone { get;}
}