我正在WPF棱镜和MVVM之后用C#构建桌面应用程序。该应用程序通过各种API向Web请求各种数据。我已经计划将应用程序采用利用Autofac for DI的插件体系结构的形式。 (这是我第一次使用autofac)我在理解如何编写单个插件方面没有问题,我创建了一个IPlugin接口,并弄清楚了如何注册每个新插件并为单个插件做解析部分。但是,我以正确的方式遇到困难,无法以与在其自己的dll中包含所有API特定项一致的方式来实现应用程序的特定部分。例如,我可能有一个与DataProducerA相对应的dll,该DataProducerA具有一组请求,可以通过URL查询发出该请求以获取不同种类的数据集,其中一个可能是getItemData(int id,AnEnum语言环境,params string []代码) 。在旧版本中,这些请求是使用各种静态方法组成的,这些方法采用各种参数来构建DataProducerA的请求。
我正在努力解决的主要问题是如何正确公开这些方法。我看了几个例子,如下:
Autofac - How to create a generated factory with parameters Autofac decorator + delegate factory Autofac Register Generic Delegate factory
以及官方文档: https://autofac.readthedocs.io/en/latest/advanced/delegate-factories.html
但是我不了解哪种方法对我尝试做的是正确的。我认为我在代理工厂方面走了正确的路,但是我不确定。
我认为我应该做类似以下的事情: Keyed delegate factories with runtime constructor parameters? 但是,我不确定这是否适合我的情况。
public class getDealsRequest : Request
{
public ApiSpecifcRequestType aSRequestType => ApiSpecifcRequestType.deals;
public delegate Request Factory(string x, bool y);
public string x { get; set; }
public bool y { get; set; }
getDealsRequest(string x, bool y)
{
this.x = x;
this.y = y;
}
}
public class getItemsRequest : Request
{
public ApiSpecifcRequestType aSRequestType => ApiSpecifcRequestType.items;
public delegate Request Factory(int x, string y);
public int x { get; set; }
public string y { get; set; }
getItemsRequest(int x, string y)
{
this.x = x;
this.y = y;
}
}
public abstract class Request : IRequest
{
public ApiRequestType RequestType => ApiRequestType.Api;
}
public class RequestWrangler : IRequestBuilder
{
public IRequest Request { get; private set; }
public RequestWrangler(IComponentContext context, int val, string astring)
{
var RequestFactory = context.Resolve<getItemsRequest.Factory>();
Request = RequestFactory(val, astring);
}
public RequestWrangler(IComponentContext context, string astring, bool abool)
{
var RequestFactory = context.Resolve<getDealsRequest.Factory>();
Request = RequestFactory(astring, abool);
}
}
这是我正在尝试的另一个帖子代码的修改示例,以试图更好地理解如何实现我要实现的目标。以下是我尝试转换为autofac的示例 格式:
public class ApiSpecificRequest : IApiSpecificRequest
{
public Dictionary<string, string> parameter;
public string postData;
public string path;
public ApiSpecificRequestTypes ApiSpecificRequestType { get; set; }//getDeals, getItems, etc
public ApiTypes RequestType { get; set; }//API
public ApiSpecificRequest()
{
parameter = new Dictionary<string, string>(20);
}
public static ApiSpecificRequest getDealsRequest(DealRequest dealRequest)
{
ApiSpecificRequest r = new ApiSpecificRequest();
r.RequestType = RequestTypes.API;
r.ApiSpecificRequestType = ApiSpecificRequestTypes.DEALS_REQUEST;
r.path = "deal";
r.postData = JsonConvert.SerializeObject(dealRequest);
return r;
}
public static ApiSpecificRequest getTrackingListRequest(bool codesOnly)
{
ApiSpecificRequest r = new ApiSpecificRequest();
r.RequestType = RequestTypes.API;
r.ApiSpecificRequestType = ApiSpecificRequestTypes.TRACKING_LIST;
r.path = "tracking";
r.parameter.Add("type", "list");
if (codesOnly)
r.parameter.Add("codes-only", "1");
return r;
}
}
我要执行的想法是,用户应能够根据可用的dll来传递这些特定于API的请求,传递任何必需的参数,因此,如果他们具有DataProducerAs插件,则他们可以访问与构建相关的方法DataProducerAs请求。构造请求后,可以将其作为IRequest返回,并带有一个enum属性,该属性指示该请求属于哪个API。
因此,这也许可以澄清我不明白的内容。如果我解决了IPlugin,如何获得正确的响应?
public interface IPlugin
{
Task<int> Process(BroadcastBlock<byte[]> buffer);
IRequest BuildQuery(bool codesOnly); //maybe?
}
var component = scope.Resolve<IPlugin>()
component.buildQuery(dealRequest)
component.buildQuery(codesOnly)
此外,如果您知道我可以参考或参考的所有详尽示例,则可以很高兴地找到解决相同问题的方法,这是完成我正在尝试的更好的方法,或者显示我的思维过程有误