VB/VB.Net Questions diverse sur l'architecture

Inscrit
31 Mars 2012
Messages
102
Reactions
0
#1
Bonjour tout le monde :mrgreen:

Alors voila, je code mon bot depuis un petit temps, je finis tout le temps par arrêter par manque de temps et d'envie.
Mais cette fois si (je l'espère) c'est la bonne.

Et j'ai besoin de votre aide, j'arrive à codé mon MITM "sans problème" si ce n'est l'architecture.

J'ai essayé plusieurs architecture, et pour le moment, après 3 ou 4 refonte, une seule me semble propre.

Voici le coeur de celle-ci :

Code:
Imports System.Net.Sockets
Imports FriendlyBot.API
Imports FriendlyBot.Engine
Imports FriendlyBot.Engine.Managers
Imports FriendlyBot.GUI

Public Class Manager
    Implements IDisposable

#Region "Var & events"

    Private WithEvents MainLogs As Logs
    Private WithEvents ThemeSelector As ThemeSelector
    Private WithEvents PluginLoader As PluginLoader
    Private WithEvents DofusConnectionListener As DofusConnectionListener
    Private WithEvents DofusInjector As DofusInjector
    Private WithEvents DofusRawManager As DofusRawManager

    Private WithEvents MainForm As MainForm
    Private WithEvents OptionsForm As OptionsForm
    Private WithEvents PluginForm As PluginForm

    Public Sub New()
        MainLogs = New Logs
        MainLogs.Add("Logs Initialized", API.LogType.Debug)
        ThemeSelector = New ThemeSelector
        MainLogs.Add("ThemeSelector Initialized", API.LogType.Debug)
        PluginLoader = New PluginLoader
        MainLogs.Add("PluginLoader Initialized", API.LogType.Debug)
        DofusConnectionListener = New DofusConnectionListener
        MainLogs.Add("DofusConnectionListener Initialized", API.LogType.Debug)
        DofusInjector = New DofusInjector
        MainLogs.Add("DofusInjector Initialized", API.LogType.Debug)
        DofusRawManager = New DofusRawManager(DofusInjector) 'faudrais changé ...
        MainLogs.Add("DofusRawManager Initialized", API.LogType.Debug)

        MainForm = New MainForm(Me)
        OptionsForm = New OptionsForm(Me)
        PluginForm = New PluginForm(Me)
        MainLogs.Add("MainForm, OptionsForm and PluginForm Initialized", API.LogType.Debug)

    End Sub
    Public Sub Start()
        Application.Run(MainForm)
    End Sub

    Private Sub OnConnectionCompleted(TcpClient As TcpClient) Handles DofusConnectionListener.ConnectionCompleted
        If MainForm.InvokeRequired Then
            MainForm.Invoke(New Action(Of TcpClient)(AddressOf AddBotManager), TcpClient)
        Else
            AddBotManager(TcpClient)
        End If
    End Sub
    'Autres, par exemple MainForm.Closing pour Dispose.

#End Region

#Region "ThreadSafe methods"

    Private Sub AddBotManager(TcpClient As TcpClient)
        Throw New NotImplementedException
        'Dim BotManager As New BotManager(Me, TcpClient)
        'BotManagerList.add(BotManager) 
        'BotManager = Manager pour chaque client connecté, il gère donc le transfère Dofus <=> Server, les plugins, ..
    End Sub

#End Region

#Region "Public Methods"

    Public Sub ShowOptionsForm()
        OptionsForm.Show()
    End Sub
    Public Sub ShowPluginForm()
        PluginForm.Show()
    End Sub
    Public Sub StartDofus()
        DofusRawManager.StartDofus()
    End Sub

    Public Sub SetTheme(ThemeName As String)
        ThemeSelector.SetTheme(ThemeName)
    End Sub

    Public Function GetPluginsAttribute() As PluginAttribute()
        Return PluginLoader.GetPluginsAttribute()
    End Function
    Public Sub LoadPlugin(InstanceID As Integer)
        Throw New NotImplementedException
    End Sub
    Public Sub UnloadPlugin(p1 As Integer)
        Throw New NotImplementedException
    End Sub

#End Region

#Region "IDisposable Support"
    Private disposedValue As Boolean = False

    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                MainLogs = Nothing
                ThemeSelector = Nothing
                PluginLoader = Nothing
                DofusInjector = Nothing
                DofusRawManager = Nothing
            End If

            DofusConnectionListener.Dispose()
            DofusConnectionListener = Nothing
            MainForm.Dispose()
            MainForm = Nothing
            OptionsForm.Dispose()
            OptionsForm = Nothing
            PluginForm.Dispose()
            PluginForm = Nothing

        End If
        Me.disposedValue = True
    End Sub

    Protected Overrides Sub Finalize()
        Dispose(False)
        MyBase.Finalize()
    End Sub
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

#End Region

End Class
Voilà, même si le code n'est pas complet, il représente bien l'architecture et j'aimerais savoir votre avis sur cette architecture, voire une autre proposition, avant que je code tout.. Merci.

Ps : je sais que je ne respecte pas certaines norme de nomenclature, mais bon .. vilaines habitudes.
 
Dernière édition par un modérateur:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#2
Bonsoir,

C'est à toi de trouver l'architecture qui te correspond le mieux.

Pour ma part, j'ai l'habitude, dans une classe de créer plusieurs régions:
- "Variables"
- "Properties" // Pour les possibles propriétés
- "Builder" // pour le constructeur -> Sub New en VB.net
- "Public Methods"
- "Private Methods"
- "Events"
- "Disposable"

C#:
public class DebugPlugin : IPlugin
    {

        #region Variables

        private MainClient Client;

        private DebugControl Control;

        public List<MessageEntry> Messages;

        private object CheckLock;

        private delegate void AddMessageDelegate(MessageEntry msg);

        #endregion

        #region Properties

        public string PluginName
        {
            get
            {
                return "Debug";
            }
        }

        public string Author
        {
            get
            {
                return "BlueDream";
            }
        }

        public string Version
        {
            get
            {
                return "1.0.0";
            }
        }

        #endregion

        #region Methods

        public IPlugin GetInstance()
        {
        }

        public void LoadPlugin(MainClient client)
        {
        }

        public void UnloadPlugin()
        {
        }

        public void ClearMessages()
        {
        }

        private void AddMessage(MessageEntry msg)
        {
        }

        #endregion

        #region Events

        private void MessageReceived(object sender, AmaknaCore.Debug.Client.Network.ClientNetwork.MessageReceivedEventArgs e)
        {
        }

        private void MessageSent(object sender, AmaknaCore.Debug.Client.Network.ClientNetwork.MessageSentEventArgs e)
        {
        }

        #endregion

    }

Après cela dépend des cas de figure, ce ne sera pas toujours la même chose pour une classe, un formulaire, un handler mais l'important c'est de respecter des règles que tu te définis toi même.

Il faut aussi gérer minutieusement ta manière de gérer l'organisation des dossiers et des classes.


Sinon c'est déjà pas mal ce que tu as fait, penses à bien respecter la POO.
 
Dernière édition:
Inscrit
31 Mars 2012
Messages
102
Reactions
0
#3
Merci d'avoir répondu.

Mais par :

"penses à bien respecter la POO."
Tu veux dire quoi ? ne pas utilisé de module ("Shared") ?

Et le problème, c'est que avec mes 3 autres architectures, j'avais toujours, à un moment un problème que je ne pouvais pas réglé si ce n'est d'une manière dégeu .. C'est pour ça que je demandais conseil ^^'

Ps : Pour t'es Plugin, j'ai pas fais comme ça et je te conseillerais de faire de même car tu dois instancier les plugins pour récupéré leur nom, ..

Code:
<AttributeUsage(AttributeTargets.Assembly, AllowMultiple:=True)>
Public Class PluginAttribute
    Inherits Attribute

    Public ReadOnly Plugin As Type
    Public ReadOnly PluginType As PluginType
    Public ReadOnly Name As String
    Public ReadOnly Description As String
    Public ReadOnly Author As String
    Public ReadOnly InstanceID As Integer = Donnator.GetID

    Public Sub New(Plugin As Type, PluginType As PluginType, Name As String, Description As String, Author As String)
        Me.Plugin = Plugin
        'Si tu veux que ton Plugin Inherits qqch, tu peux faire :
        'If Not Plugin.IsAssignableFrom(TonBaseType) then Throw ... 
        Me.PluginType = PluginType
        Me.Name = Name
        Me.Description = Description
        Me.Author = Author
    End Sub

End Class

'Utilisation : 

<Assembly: Plugin(GetType(MigrationPlugin), API.PluginType.BotPlugin, "Migration Plugin", "Ce plugin permet la connection au serveur de jeux", "Nicogo")> 

Public Class MigrationPlugin
....
End Class
 
Dernière édition par un modérateur:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#4
Ahah merci du conseil, mais c'est un système modulaire avancé, je dois respecter cette mise en forme. Je ne peux pas utiliser de reflection.

Sinon le Shared n'est pas du tout un problème, j'ai un dossier Managers qui ne contient que des classes static (Shared en VB).

Quand je parle de POO, je parle de Programmation Orientée Objet.
http://xo.developpez.com/tutoriel/vb.net/poo/
 
Inscrit
31 Mars 2012
Messages
102
Reactions
0
#5
Merci, même si je sais c'est quoi la POO, je ne connais pas toutes les règles, je vais lire ça :)
 
Haut Bas