从子

时间:2015-11-18 23:33:16

标签: c# .net

我在Class 1中有一个List。 我有一个辅助类(Class 2),它在Class 1中实例化。 然后,第2类应该做一些工作并更新第1类中的List。

我尝试将Class 1传递给Class 2的构造函数,但这只会修改Class 2中的版本。

public class Server // Class 1
{

    private string m_serverName;
    private string m_loginUsername;
    private string m_loginPassword;
    private ServerConnectionTools m_connectionTools;
    public List<Service> Services { get; private set; }

    public Server(string serverName, string loginUsername, string loginPassword)
    {
        this.ServerName = serverName;
        this.LoginUsername = loginUsername;
        this.LoginPassword = loginPassword;

        // Login to server and retrieve list of services
        ConnectionTools = new ServerConnectionTools(this);

    }
}


public class ServerConnectionTools // Class 2
{
    private Server m_server;
    private ManagementScope m_scope;

public ServerConnectionTools(Server server)
    {
        this.Server = server;
        this.Scope = InitiateScope();

        try
        {
            // Once this is finished updating, I need to update the Service List in Class 1.
            this.UpdateServicesList();
        }
        catch (System.Runtime.InteropServices.COMException)
        {
            // Server is unavailable
            Console.WriteLine("Unable to reach server {0}", server.ServerName);
        }
    }

    public ManagementScope InitiateScope()
    {
        ManagementScope scope;

        // If server is Remote server, log in with Credentials
        // otherwise no need to connect.
        if (System.Environment.MachineName.ToLower() != this.Server.ServerName.ToLower())
        {
            // Is a remote server, need credentials
            ConnectionOptions options = new ConnectionOptions();

            options.Username = this.Server.LoginUsername;
            options.Password = this.Server.LoginPassword;

            scope = new ManagementScope("\\\\" + this.Server.ServerName + "\\root\\cimv2", options);

        }
        else
        {
            // Local machine, no need for credentials
            scope = new ManagementScope("\\\\" + this.Server.ServerName + "\\root\\cimv2");
        }
        return scope;
    }


    public void UpdateServicesList()
    {
        // Connect our scope to the actual WMI scope
        this.Scope.Connect();

        List<StringBuilder> servicesList = new List<StringBuilder>();


        // Query system for Services
        ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service WHERE Caption LIKE 'xxx%'");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(this.Scope, query);
        ManagementObjectCollection services = searcher.Get();

        if (services.Count > 0)
        {
            foreach (ManagementObject queryObj in services)
            {
                StringBuilder s = new StringBuilder();

                s.Append(queryObj["Caption"].ToString());
                s.Append(",");
                s.Append(queryObj["State"].ToString());
                s.Append(",");
                s.Append(queryObj["ProcessId"].ToString());
                s.Append(";");

                servicesList.Add(s);
            }


        }
    }

编辑:添加代码,认为我做得很好,保持简单! 所以当我运行this.UpdateServicesList();在ServerConnectionTools类的构造函数中,我需要更新Server类中的List。

Edit2:在输入时我有一个脑波...从更新函数返回服务列表并从第一个类调用更新函数。认为这是一种更好的方法吗?

这样做的最佳方法是什么?

道歉可能是一个简单的问题...

干杯 戴夫

3 个答案:

答案 0 :(得分:1)

修改:修改后删除了代码段。

是,返回服务列表。这比将父类发送给辅助类要好得多。

您似乎没有使用发送到帮助程序类的服务器。所以你可以从更新功能中获取服务。我会将更新函数重命名为FetchServices,而不是更新。

public Server(string serverName, string loginUsername, string loginPassword)
{
    this.ServerName = serverName;
    this.LoginUsername = loginUsername;
    this.LoginPassword = loginPassword;

    // Login to server and retrieve list of services
    ConnectionTools = new ServerConnectionTools(this);
    this.Services = ConnectionTools.FetchServiceTools();
}

答案 1 :(得分:0)

使用代表。

像这样:

// Delegate Specification
    public class MyClass
    {
        // Declare a delegate that takes a single string parameter
        // and has no return type.
        public delegate void LogHandler(string message);

        // The use of the delegate is just like calling a function directly,
        // though we need to add a check to see if the delegate is null
        // (that is, not pointing to a function) before calling the function.
        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler ("Process() end");
            }
        }
    }

    // Test Application to use the defined Delegate
    public class TestApplication
    {
        // Static Function: To which is used in the Delegate. To call the Process()
        // function, we need to declare a logging function: Logger() that matches
        // the signature of the delegate.
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }

        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();

            // Crate an instance of the delegate, pointing to the logging function.
            // This delegate will then be passed to the Process() function.
            MyClass.LogHandler myLogger = new MyClass.LogHandler(Logger);
            myClass.Process(myLogger);
        }
    }

答案 2 :(得分:0)

在您的情况下,您不需要serviceConnectionTools中的整个服务类。 这是我对你的建议 步骤1添加界面

interface caller
{
  void setList(List<StringBuilder> par_list);

}

步骤2实现界面 public class Server:caller {

private string m_serverName;
private string m_loginUsername;
private string m_loginPassword;
private ServerConnectionTools m_connectionTools;
public List<Service> Services { get; private set; }

public Server(string serverName, string loginUsername, string loginPassword)
{
    this.ServerName = serverName;
    this.LoginUsername = loginUsername;
    this.LoginPassword = loginPassword;

    // Login to server and retrieve list of services
    ConnectionTools = new ServerConnectionTools(this);

}
public void setList(List<StringBuilder> par_list)
{
      //do whatever you need to here.
}

}

第3步

public class ServerConnectionTools // Class 2
{
    private caller m_serverCB;
    private ManagementScope m_scope;

public ServerConnectionTools(caller par_serverCB)
    {
        m_serverCB = par_serverCB;
    this.Scope = InitiateScope();

    try
    {

        this.UpdateServicesList();

    }
    catch (System.Runtime.InteropServices.COMException)
    {
        // Server is unavailable
        Console.WriteLine("Unable to reach server {0}", server.ServerName);
    }
}
您的Updateservicelist函数中的

///

 public void UpdateServicesList()
    {
        // Connect our scope to the actual WMI scope
        this.Scope.Connect();

        List<StringBuilder> servicesList = new List<StringBuilder>();

    // Query system for Services
    ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service WHERE Caption LIKE 'xxx%'");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(this.Scope, query);
    ManagementObjectCollection services = searcher.Get();

    if (services.Count > 0)
    {
        foreach (ManagementObject queryObj in services)
        {
            StringBuilder s = new StringBuilder();

            s.Append(queryObj["Caption"].ToString());
            s.Append(",");
            s.Append(queryObj["State"].ToString());
            s.Append(",");
            s.Append(queryObj["ProcessId"].ToString());
            s.Append(";");

            servicesList.Add(s);
        }


    }
     m_serverCB.setList(servicesList);//add this to call method.
}

现在您不必将所有服务器对象发送到class2。您可以将serverConnectionTools用于将来可能需要的其他类别,而不是仅使用一个类。现在我希望您有更好的oop实现。