C# 为不同的客户端加载不同的程序集或模块

C# 为不同的客户端加载不同的程序集或模块,c#,asp.net-mvc,C#,Asp.net Mvc,我在.NET4.5中开发了一个web应用程序,现在一位客户要求我定制某个应用程序模块(例如发票的不同实现)。 我的问题是,我是否可以“拦截”我的客户以加载自定义装配,并为普通客户加载不同的装配 我可以简单地通过反射来实现吗?关键思想是以易于更换的方式设计软件。您应该将解决方案分为多个项目,以便可以快速交换接口的不同实现 此外,还有一种称为依赖项注入的东西,这基本上意味着您可以根据需要在运行时或使用配置文件(例如)注入不同的实现。为了便于使用,已经为您准备了一些不错的框架,比如Ninject或Un

我在.NET4.5中开发了一个web应用程序,现在一位客户要求我定制某个应用程序模块(例如发票的不同实现)。 我的问题是,我是否可以“拦截”我的客户以加载自定义装配,并为普通客户加载不同的装配


我可以简单地通过反射来实现吗?

关键思想是以易于更换的方式设计软件。您应该将解决方案分为多个项目,以便可以快速交换接口的不同实现

此外,还有一种称为依赖项注入的东西,这基本上意味着您可以根据需要在运行时或使用配置文件(例如)注入不同的实现。为了便于使用,已经为您准备了一些不错的框架,比如Ninject或Unity


应用程序需要有一个坚实的体系结构来支持这种可能性。如果您提供了更多关于您的系统的信息,我可能会说得更具体一些,但我相信对依赖注入进行一些研究会给您一个良好的开端。

关键思想是以易于更换其部件的方式设计软件。您应该将解决方案分为多个项目,以便可以快速交换接口的不同实现

此外,还有一种称为依赖项注入的东西,这基本上意味着您可以根据需要在运行时或使用配置文件(例如)注入不同的实现。为了便于使用,已经为您准备了一些不错的框架,比如Ninject或Unity


应用程序需要有一个坚实的体系结构来支持这种可能性。如果您提供了更多关于您的系统的信息,我可能会说得更具体一些,但我相信对依赖注入进行一些研究会给您一个良好的开端。

是的,您可以。可以从文件中加载程序集,如下所示
var asmbly=System.Reflection.Assembly.LoadFrom(路径)
然后使用反射加载类型

有几种方法可以实现这种可插拔性。一种方法是提取“模块”的接口,并针对该接口编写“模块客户机”代码,将具体实现与“客户机”代码分离。然后,在运行时查看组件内部,加载实现所述接口的类型并注入“模块客户端”

我在这里粘贴了一些我写的代码,作为对“模块”运行时加载类型(这是MVC 3)的概念证明:

请注意,这种类型的编程需要更多的权限—我对这段代码已经“生疏”了几年,但我记得信任级别的问题,当然,还必须考虑文件系统访问



有一些框架可以帮助实现这种应用程序风格。这又是几年前的事了,但在微软的模式与实践网站上曾经有一个所谓的“复合应用程序块”,它是两个框架的基础——Smart Cliet Softweare Factory和它的web等价物——web客户端软件Factory。它们有点笨重,但为此类模块化(复合)应用程序提供了良好的框架。

是的,您可以。可以从文件中加载程序集,如下所示
var asmbly=System.Reflection.Assembly.LoadFrom(路径)
然后使用反射加载类型

有几种方法可以实现这种可插拔性。一种方法是提取“模块”的接口,并针对该接口编写“模块客户机”代码,将具体实现与“客户机”代码分离。然后,在运行时查看组件内部,加载实现所述接口的类型并注入“模块客户端”

我在这里粘贴了一些我写的代码,作为对“模块”运行时加载类型(这是MVC 3)的概念证明:

请注意,这种类型的编程需要更多的权限—我对这段代码已经“生疏”了几年,但我记得信任级别的问题,当然,还必须考虑文件系统访问



有一些框架可以帮助实现这种应用程序风格。这又是几年前的事了,但在微软的模式与实践网站上曾经有一个所谓的“复合应用程序块”,它是两个框架的基础——Smart Cliet Softweare Factory和它的web等价物——web客户端软件Factory。它们有点笨重,但为这种模块化(复合)应用程序提供了更好的框架。

我只有一个单独的解决方案,并使用ninject。我的问题是,如果应用程序是SaaS,我是否可以在不为客户重新安装单独应用程序的情况下加载“模块”的版本控制程序集?如果您已经在使用ninject,并且选择了在外部文件而不是代码中定义映射的路径,那么我相信这是可能的。只需将新dll复制到应用程序文件夹中,并修改包含映射的ninject设置文件。试试看:)然而,如果你不能像这样控制它,那么我认为这就不那么容易了,你必须修改核心文件使之成为可能。可能有(不确定是否真的)一些拦截电话和其他东西的方法,但我认为这不是一个好主意。我只是有一个单独的解决方案并使用ninject。我的问题是,如果应用程序是SaaS,我是否可以在不为客户重新安装单独应用程序的情况下加载“模块”的版本控制程序集?如果您已经在使用ninject,并且选择了在外部文件而不是代码中定义映射的路径,那么我相信这是可能的。只需将新dll复制到应用程序文件夹中,并修改包含映射的ninject设置文件。试一试:)然而,如果你不能像这样控制它,那么我认为这就不那么容易了,你必须修改核心文件,使它成为p
// "Module User" was decoupled from "module", by coding it against module's interface:
public class CustomerController : Controller
{
    private ICustomerRepository _customerRepository;

    // dependency injection constructor
    public CustomerController(
            ...
            ICustomerRepository customerRepository,
            ...)
    {
            _customerRepository = customerRepository;
    }


    public ActionResult Details(Nullable<Guid> id)
    {
            Customer c = _customerRepository.GetByKey(id.Value.ToString());
            ...
    }

    ...
} 
// I first load the assembly
System.Reflection.Assembly dal = System.Reflection.Assembly.LoadFrom(System.IO.Path.Combine(pBinPath, pDALAssemblyName));

// I then look for types implementing ICustomerRepository 
var addressRepositoryContract = typeof(QSysCamperCore.Domain.IAddressRepository);
var addressRepositoryImplementation = dal.GetTypes()
    .First(p => addressRepositoryContract.IsAssignableFrom(p));
...