1

我有一个 Windows 服务,它查看 dll 列表(在设置文件中),将它们全部加载,并在每个 dll 中在其自己的线程中启动特定方法。这些 dll 中的每一个都必须从特定类(模块类)继承才能被此服务使用,并且该类的一部分是 MPI 对象,基本上是一个类的实例,它允许 dll 方法调用方法以直接与之交互服务。它是如何进行的:

  1. 服务加载 dll
  2. 使用反射检查是否有继承Module类的类
  3. 创建该 Module 继承类的新实例
  4. 创建 MPI 类的新实例。这有关于哪个模块正在使用它的识别信息
  5. 将新创建的 MPI 对象分配给新的 Module 类
  6. 启动主模块线程

基模块类本身就是它自己的 dll(以便服务和外部 dll 都可以使用它)。我想要做的是让服务能够为新的 Module 类分配一个具有特殊值的 MPI 对象,但我不希望该类能够更改 MPI 对象分配或任何值在里面。ReadOnly 用于继承的类,但可从其他类分配。我想我不能按照我的设置方式来做到这一点,我必须做些什么改变才能做到这一点。甚至可能吗?

MPI 几乎就像主要托管服务的 API。它处理一些集中的事情,比如错误记录。当服务加载一个新模块时,它会为其分配一个 ID。当该模块调用时MPI.ErrorLog(someStuff),具有对主服务内存的引用并因此可以访问实际错误写入器的 MPI 将写入此时模块 ID # 有此错误。我希望 ID 对继承 Module 的类是私有的,而不是对主服务私有,以便 ID 可以由它设置。不要用设置所有内容的构造函数说私有变量,因为我不希望模块本身能够创建新的 MPI 对象并能够改变这些东西。

4

2 回答 2

2

据我了解,您想为不同的上下文/用户修改对单个对象的访问。例如,'base' 知道 get 和 set 访问器,而 'module' 只知道 get 访问器。我可以在这里想象两个选项 - 访问修饰符和接口。

首先,internal修饰符使成员仅对同一程序集中的文件可见。

public class Mpi
{
    private int id;

    int Id
    {
        public get
        {
            return this.id;
        }
        internal set
        {
            this.id = value;
        }
    }
    //...
}

因此,您的“模块”将假定这是一个仅获取属性,而您的“基础”将能够获取和设置。

您的第二个选择是拥有一个仅定义 get 访问器的接口。

public interface IMpi
{
    int Id { get; }
}

public class Mpi : IMpi
{
    public int Id { get; set; }
}

在此模型中,“基”类使用Mpi对象,“模块”类使用IMpi对象。它们是同一个实例,但模块也不知道该Id属性有一个 set 方法。

于 2013-02-13T04:21:38.353 回答
0

假设你有:

var modules = from file in Directory.GetFiles(path, "*.dll").AsParallel()
              from type in Assembly.LoadFile(file).GetTypes().AsParallel()
              where !type.IsInterface && typeof(Module).IsAssignableFrom(type)
              select (Module)Activator.CreateInstance(type);

然后你声明你的 Module 基类:

public abstract class Module
{
    public abstract Mpi Mpi { get; set; } // to inherit you must implement getter (you don't need it) and setter (what you're asking about)

    public abstract void Main(); // to inherit you must implement too
}

并使用:

Mpi mpi = new Mpi();
foreach (Module m in modules)
{
     m.Mpi = mpi;
     m.Main();
}

另一种解决方案。如果基类有一个无参数构造函数,它将始终被调用。在里面你只能分配一个基类可写的变量:

public abstract class Module
{
    protected Module()
    {
        this.Mpi = new Mpi();
    }

    protected Mpi Mpi { get; private set; } // getter is visible to children, setter only for class itself
}
于 2013-02-13T04:52:35.357 回答