Ketergantungan melingkar saat menambahkan referensi (Delegasi)

Pada dasarnya saya punya 2 proyek, formulir dan kontrol pengguna.

Saya memerlukan keduanya untuk berada di proyek yang berbeda tetapi formulirnya perlu merujuk ke kontrol pengguna karena menggunakan kontrol pengguna. Dan kontrol pengguna perlu merujuk ke formulir karena menggunakan salah satu kelas formulir. Ketika saya menambahkan yang kedua karena memerlukan , VS akan mengeluhkan ketergantungan melingkar yang dapat dimengerti. Bagaimana cara mengatasi ini?


person user3398315    schedule 22.04.2014    source sumber
comment
Bisakah Anda mengabstraksi kelas non-UI dari proyek Formulir dan membuat DLL?   -  person shree.pat18    schedule 22.04.2014
comment
Buat proyek ketiga yang berisi semua baik yang dibutuhkan formulir dan kontrol pengguna. Anda tidak akan pernah membuat bangunan Anda berfungsi dengan benar tanpa melakukan hal itu.   -  person Peter Ritchie    schedule 22.04.2014


Jawaban (4)


Logikanya formulir harus bergantung pada kontrol pengguna. Anda dapat membuat antarmuka untuk menggantikan formulir dalam proyek kontrol pengguna, dan kemudian meminta formulir mengimplementasikan antarmuka tersebut.

Contoh proyek kontrol pengguna;

public interface IForm
{
    string MyString { get; }
}

public class MyUserControl : UserControl
{
     public IForm Form { get; set; }

     private void ShowMyString()
     {
          String myString = Form.MyString;
          ...
     }
}

Contoh Formulir proyek

public class MyForm : Form, IForm
{
    public MYString { get "My String Value"; }
}
person Adrian Toman    schedule 22.04.2014

Saya pikir akar penyebab masalah Anda adalah Anda belum memisahkan kekhawatiran Anda antara bentuk dan kontrol dengan benar.

Karena Anda memiliki kontrol (agak umum), kontrol tersebut tidak bergantung pada formulir. Seluruh logika kendali harus berada di dalam kendali itu sendiri. Formulir hanya boleh menggunakan kontrol kotak hitam: menambahkannya, mengatur bidang publik, memanggil metode publik, dll. Yang lainnya merupakan pelanggaran enkapsulasi.

Terkadang, kontrol mungkin perlu mengetahui beberapa hal tentang bentuk induknya. Dalam hal ini, saya akan menyarankan sesuatu yang sederhana seperti menambahkan bidang Parent ke kontrol anak.

jika Anda memerlukan sesuatu yang lebih spesifik dari formulir, Anda selalu dapat menambahkan antarmuka; antarmuka seharusnya hanya mencantumkan hal-hal yang diperlukan kontrol dari formulir. Misalnya, jika Anda memerlukan ukurannya, Anda dapat menambahkan:

public interface IControlParent {
  int Width { get; }
  int Height { get; }
}

Dengan cara ini, Anda melihat dengan jelas dependensinya (apa yang dibutuhkan kontrol dari induknya), dan jika jenis/kontrak induknya berubah, Anda tidak perlu melakukan banyak hal untuk mengubah kelas kontrol Anda.

person ashes999    schedule 22.04.2014

Anda harus memisahkan kode Anda, tidak ada gunanya memiliki referensi ke rakitan aplikasi, jika Anda mencoba menggunakannya kembali di masa mendatang, exe aplikasi harus disertakan dengan kontrol.

Jadi, ambil kelas dari proyek formulir dan pindahkan ke proyek kontrol atau buat proyek perpustakaan, letakkan kelas di dalamnya dan referensikan dari kontrol dan proyek aplikasi Anda.

person Gusman    schedule 22.04.2014

Anda harus menggunakan suatu acara (delegasi). Mari kita asumsikan bahwa di dalam proyek formulir Anda membuat satu kelas: Form1. Dan di dalam kontrol pengguna Anda mendefinisikan UserControl1. UserControl1 perlu membuat instance dan memanggil metode dari Form1:

public class Form1
{
    public void Execute(string sMessage)
    {
        Console.WriteLine(sMessage);
        Console.ReadLine();
    }
}

Kontrol Pengguna1:

public class UserControl
{
    public Func<object, object> oDel = null;

    public void Execute()
    {
        oDel?.Invoke("HELLO WORLD!");
    }
}

Dan dari kelas yang membuat instance UserControl, sebut saja ParentClass:

public class ParentClass
{
    public void Execute()
    {
        UserControl oUserControl = new UserControl();
        oUserControl.oDel = Form1Action;
        oUserControl.Execute();
    }

    public object Form1Action(object obj)
    {
        string sObj = Convert.ToString(obj);

        Form1 oForm = new Form1();
        oForm.Execute(sObj);

        return null;
    }
}

Pendekatan ini memberikan tanggung jawab penanganan suatu event kepada kelas tingkat tinggi.

person Andrés    schedule 04.04.2017