Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用静态方法代替Spec_C#_.net_Unit Testing_Mspec_Fody - Fatal编程技术网

C# 用静态方法代替Spec

C# 用静态方法代替Spec,c#,.net,unit-testing,mspec,fody,C#,.net,Unit Testing,Mspec,Fody,我在试着用这个。我已经创建了替换,但是依赖代码不调用替换 代替 [StaticReplacement(typeof(AppUtils))] 公共静态类apputilssubstitute { 公共静态void LogException(string func,Exception ex)=>Write(“Exception”,ex.ToJson()); 公共静态void LogError(字符串err)=>Write(“Error”,err); 公共静态void LogInfo(string in

我在试着用这个。我已经创建了替换,但是依赖代码不调用替换

代替
[StaticReplacement(typeof(AppUtils))]
公共静态类apputilssubstitute
{
公共静态void LogException(string func,Exception ex)=>Write(“Exception”,ex.ToJson());
公共静态void LogError(字符串err)=>Write(“Error”,err);
公共静态void LogInfo(string info)=>Write(“info”,info);
公共静态无效日志警告(字符串信息)=>写入(“警告”,信息);
公共静态void LogCypherQuery(string func,ICypherFluentQuery query)=>Write(func,query.ToJson());
静态无效写入(字符串日志类型、字符串消息)
{
var dictionary=新字典{{logType,message};
var assembly=assembly.getExecutionGassembly();
使用(var writer=newstreamwriter(assembly.Location+“Machine.Specifications.log”))
{
Write(dictionary.ToJson());
}
}
公共静态字典日志()
{
var assembly=assembly.getExecutionGassembly();
词典内容;
使用(var reader=newstreamreader(assembly.GetManifestResourceStream(“Machine.Specifications.log”))
{
content=JsonConvert.DeserializeObject(reader.ReadToEnd());
}
返回内容;
}
}
相依法
[AttributeUsage(AttributeTargets.Method)]
公共类EnsunceRepresentationsOfAttribute:ActionFilterAttribute
{
需要内部虚拟字符串{get;}
内部虚拟字符串参数{get;}
public-ensureRepresentencesOfAttribute(string required=“”,string param=“request”)
{
必需=必需;
Param=Param;
}
公共重写无效OnActionExecuting(HttpActionContext actionContext)
{
字典模型=actionContext.ActionArguments;
if(model==null | | | model.Count==0 | |!model.ContainsKey(Param))
{
ValueError(actionContext,$“{Param}参数”);
返回;
}
foreach(Required.Split(',')中的var需求。选择(e=>e.Trim())
{
if(型号[要求]==null)
{
ValueError(操作上下文、要求);
返回;
}
}
base.OnActionExecuting(actionContext);
}
公共覆盖任务OnActionExecutingAsync(HttpActionContext上下文,CancellationToken令牌)
{
字典模型=context.ActionArguments;
if(model==null | | | model.Count==0 | |!model.ContainsKey(Param))
{
ValueError(上下文,$“{Param}参数”);
返回Task.FromResult(0);
}
foreach(Required.Split(',')中的var需求。选择(e=>e.Trim())
{
if(型号[要求]==null)
{
ValueError(上下文、要求);
Task.FromResult(0);
}
}
返回base.OnActionExecutingAsync(上下文,令牌);
}
私有静态void ValueError(HttpActionContext上下文,字符串要求)
{
var action=context.ActionDescriptor.ActionName;
LogError($“{action}失败:缺少必需的属性{requirement}”);
使用(var controller=new BaseApiController{Request=new HttpRequestMessage()})
{
controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey,new-HttpConfiguration());
context.Response=controller.InvalidInputResponse();
}
}
}

静态依赖关系往往使维护和测试与其紧密耦合的代码变得困难

ASP.NET Web API提供了可扩展性点,以避免此类依赖关系。主要是用于的
IDependencyResolver

因此,我建议将静态实用程序转换为抽象,或者至少将其抽象到一个易于替换的接口后面

public interface ILogger {
    void LogException(string func, Exception ex);
    void LogError(string err);
    void LogInfo(string info);
    void LogWarning(string info);
    void LogCypherQuery(string func, ICypherFluentQuery query);
    Dictionary<string, string> Log();
}
只需确保在启动时使用您选择的IoC容器配置依赖项解析器

在的
dependencysolver
属性上设置依赖项解析器 全局
HttpConfiguration
对象

下面的代码将
ILogger
接口注册为Unity和 然后创建一个
UnityResolver

public static void Register(HttpConfiguration config)    {
    var container = new UnityContainer();
    container.RegisterType<ILogger, AppUtilsSubsitute>(new HierarchicalLifetimeManager());
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.    
}
公共静态无效寄存器(HttpConfiguration配置){
var container=new UnityContainer();
RegisterType(新的层次结构CallifetimeManager());
config.DependencyResolver=新的UnityResolver(容器);
//未显示其他Web API配置。
}
public interface ILogger {
    void LogException(string func, Exception ex);
    void LogError(string err);
    void LogInfo(string info);
    void LogWarning(string info);
    void LogCypherQuery(string func, ICypherFluentQuery query);
    Dictionary<string, string> Log();
}
public class AppUtilsSubsitute : ILogger {
    public void LogException(string func, Exception ex) => Write("Exception", ex.ToJson());

    public void LogError(string err) => Write("Error", err);

    public void LogInfo(string info) => Write("Info", info);

    public void LogWarning(string info) => Write("Warning", info);

    public void LogCypherQuery(string func, ICypherFluentQuery query) => Write(func, query.ToJson());

    static void Write(string logType, string message) {
        var dictionary = new Dictionary<string, string> { { logType, message } };
        var assembly = Assembly.GetExecutingAssembly();
        using (var writer = new StreamWriter(assembly.Location + "Machine.Specifications.log")) {
            writer.Write(dictionary.ToJson());
        }
    }

    public Dictionary<string, string> Log() {
        var assembly = Assembly.GetExecutingAssembly();
        Dictionary<string, string> content;
        using (var reader = new StreamReader(assembly.GetManifestResourceStream("Machine.Specifications.log"))) {
            content = JsonConvert.DeserializeObject<Dictionary<string, string>>(reader.ReadToEnd());
        }
        return content;
    }
}
private static void ValueError(HttpActionContext context, string requirement) {
    var httpConfiguration = context.RequestContext.Configuration;
    var resolver = httpConfiguration.DependencyResolver;
    var logger = resolver.GetService(typeof(ILogger));
    var action = context.ActionDescriptor.ActionName;
    logger.LogError($"{action} Failed : Missing Required Attribute {requirement}. ");
    using (var controller = new BaseApiController { Request = new HttpRequestMessage() }) {
        //USE THE GLOBAL HTTPCONFIGURATION ALREADY ASSOCIATED WITH THE
        //REQUEST INSTEAD OF CREATING A NEW ONE THAT HAS NONE OF THE 
        //WEB API CONFIG THAT WOULD HAVE BEEN ADDED AT STARTUP
        controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, httpConfiguration);
        context.Response = controller.InvalidInputResponse();
    }
}
public static void Register(HttpConfiguration config)    {
    var container = new UnityContainer();
    container.RegisterType<ILogger, AppUtilsSubsitute>(new HierarchicalLifetimeManager());
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.    
}