存在不同装配体时的部分/扩展类或接口

如何解决存在不同装配体时的部分/扩展类或接口

| 我使用一种方法来处理异常-在内部它会写入数据库,但是当发布到网络上时,源代码将不包含写入数据库所需的连接字符串。相反,它应该写入日志文件。 当不存在Foo.Private.dll时,是否可以容纳写入日志,而当存在Foo.Private.dll时,是否可以写入数据库?
//In Foo.Public.dll assembly
public class SimpleLogWriter
{
    public virtual void LogError(Exception ex)
    {
        //Write to log file.
    }
}
...
//In Foo.Private.dll assembly
public class ExtendedLogWriter : SimpleLogWriter
{
    public override void LogError(Exception ex)
    {
        //Write to database
    }
}
我曾考虑过让两个日志类实现一个共享的接口(而不是扩展和覆盖)并创建一些工厂方法来呈现它,但是不确定如何验证程序集的存在或使用其类型而不添加引用,在这种情况下最终项目将具有循环引用。     

解决方法

        这听起来像.NET 4.0中提供的Managed Extensibility Framework(MEF)的潜在用例。     ,        我可以想到几种方法可以实现此目的。 紧密耦合 使用反射来检测DLL的存在。如果存在,请加载适当的类,并对其进行额外的调用。 为此,请使用Assembly.LoadFile,Assembly.GetType(string)和Activator.CreateInstance(type)。将新实例强制转换为抽象的基本记录器类型/接口。 这或多或少是您所描述的。不过,我不建议这样做,因为它不是很灵活,并且有不错的选择。 松耦合 创建一个接口或抽象记录器类,然后使用“依赖注入”(控制反转)将记录器注入需要进行记录的组件中。如果选择,则可以使用依赖项注入库以松散耦合的方式指定所需的实现。配置DI库以从您的额外DLL(如果存在)中加载依赖项。 Castle.Windsor具有松耦合的日志记录接口(日志记录工具),您可以在第二种选择中进行研究。 这些之间也有某种频谱。 这是将记录器作为依赖项注入的要点(尽管在此示例中我未使用任何库):
using System;
using System.IO;

public interface ILogger
{
    void WriteDebug(string debug);
    void WriteInfo(string info);
    void WriteError(string error);
}

public class NullLogger : ILogger
{
    private static ILogger instance = new NullLogger();

    // This singleton pattern is just here for convenience.
    // We do this because pattern has you using null loggers constantly.
    // If you use dependency injection elsewhere,// try to avoid the temptation of implementing more singletons :)
    public static ILogger Instance
    {
        get { return instance; }
    }

    public void WriteDebug(string debug) { }
    public void WriteInfo(string info) { }
    public void WriteError(string error) { }
}

public class FileLogger : ILogger,IDisposable
{
    private StreamWriter fileWriter;

    public FileLogger(string filename)
    {
        this.fileWriter = File.CreateText(filename);
    }

    public void Dispose()
    {
        if (fileWriter != null)
            fileWriter.Dispose();
    }

    public void WriteDebug(string debug)
    {
        fileWriter.WriteLine(\"Debug - {0}\",debug);
    }

    // WriteInfo,etc
}

public class SomeBusinessLogic
{
    private ILogger logger = NullLogger.Instance;

    public SomeBusinessLogic()
    {
    }

    public void DoSomething()
    {
        logger.WriteInfo(\"some info to put in the log\");
    }

    public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }
}

public class Program
{
    static void Main(string[] args)
    {
        // You\'re free to use a dependency injection library for this,// or simply check for a DLL via reflections and load a logger from there
        using (var logger = new FileLogger(\"logfile.txt\"))
        {
            var someBusinessLogic = new SomeBusinessLogic()
            {
                // The component won\'t know which logger it is using - it just uses it
                Logger = logger,};

            someBusinessLogic.DoSomething();
        }
    }
}
    ,        听起来,这实际上仅与创建日志编写器的方式有关。与其尝试根据是否存在DLL来尝试进行操作,不如让该类实例化为整体配置的一部分。让用户(我的意思是安装它的人)如果愿意的话,请指定
ExtendedLogWriter
,如果他们拥有Foo.Private.dll,则指定
SimpleLogWriter
。有各种IoC容器可以简化这一过程。     ,        这可以通过使用控制反转来解决。 具有LogError(Exception)方法的接口IErrorLogger通过以下方式实现: DbErrorLogger FileErrorLogger 使用诸如Castle Windsor之类的控制API的倒置,您可以不同地配置IErrorLogger组件,因为ASP.NET 4.0具有Web.debug.config和Web.release.config,允许配置某些Web应用程序以进行调试和发布到Web场景。 最终,当您将编译更改为发布时,FileErrorLogger将成为IErrorLogger实现。 通过以下链接了解更多信息:http://docs.castleproject.org/Windsor.MainPage.ashx     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-