Question about Scope, I'm a bit confused.
Alright, next question!
I'm writing a .DLL (class library), and have a main class (called "Plugin") that gets loaded by the external application. In this Plugin class I have a method that gets called from the external app called "Parse", I have a somewhat large ParseIncoming function in a module all by itself, in the same project as the main Plugin.vb. I also have another .vb file that represents another Class (called Settings), which is used by the Plugin class. In the Plugiin class, I define a new instance of my Settings class.
Now, the problem shows itself when I try to make use of my instance of the Settings class (called CurrentSettings) from the module file that the ParseIncoming function is in. Basically, the CurrentSettings class isn't recognized at all by this module. I think it has something to do with scope, but I'm not sure really. Here is a summary of what should happen:
Code:
Plugin.vb contains a "Plugin" class
Settings.vb contains a "Settings" class
Parsing.vb contains a module called "ParsingFunctions" which currently contains a procedure called "ParseIncoming"
The Plugin class creates a new Settings class instance.
During runtime:
1) Plugin class gets loaded by external app
2) Plugin class contains an instance of Settings class
3) External app calls Plugin.Parse()
4) Plugin.Parse calls ParseIncoming() from the seperate module
*5) The Parsing module's ParseIncoming() procedure can't access the Plugin class's instance of the Settings class
I want to rectify step 5, and allow my module to access the Plugin class's instance of the Settings class.
I hope this wasn't too long winded, and that it makes sense! Thanks in advance.
-Brandon
Re: Question about Scope, I'm a bit confused.
Oh, also... I know I can pass the settings object ByRef to my other function when I call it, but was hoping for a way to make that object accessible to everything in my project without having to pass it around so much, as many functions will need it (it contains settings, obviously heh).
Re: Question about Scope, I'm a bit confused.
It's hard to tell exactly what the problem is without seeing code, but I have a likely suspect...
You say that in your Plugins class you create an instance of the Settings class. What access modifier are you using to declare that instance? If you're declaring it as "Private", then your module probably won't be able to see it.
Try declaring the instance of the Settings class as "Friend". This should allow anything in the same assembly to access it.
Re: Question about Scope, I'm a bit confused.
Brandon I've been working with plugins alot lately and I've found few good resources but once you wrap your head around interfaces it's pretty simple.
Here's a really good simple example that can be built upon:
http://www.divil.co.uk/net/articles/plugins/plugins.asp
Re: Question about Scope, I'm a bit confused.
DWRoelands,
I tried changing the scope of my Settings definition to Friend, to no avail. See below for what I hope to be a better explanation of my problem.
Graff,
My entire project is actually a plugin itself, for another application... I'm trying to simply make a certain class instance public to the entire project (all classes, modules, etc).
Here is a quick glimpse of my 3 files currently:
Plugin.vb (a class)
VB Code:
Public Class Plugin
Implements TheMainApplication.IPlugin
Friend Settings As New LocalSettings
... all of TheMainApplication.IPlugin interface members are here ...
Public Sub Parse(ByVal line As String)
ParseIncoming(line)
End Sub
End Class
Settings.vb (the LocalSettings class)
VB Code:
Public Class LocalSettings
Private _someVal As Integer
Public Property SomeVal() As Integer
Get
Return _someVal
End Get
Set(ByVal Value As Integer)
_someVal = Value
End Set
End Property
... Note, there are lots of other field/properties as well, but we'll stick
with just this one for now ...
End Class
Parsing.vb (a module)
VB Code:
Module Parsing
Public Sub ParseIncoming(ByVal Line As String)
... Here is where the problem comes in, I cannot access ...
... the Plugin class's instance of the LocalSettings class ...
... (called Settings) ...
Settings.SomeVal = 2 'This line fails, "Settings is not declared"
End Sub
End Module
So, that's just a run down of the problem, I can pass the Settings object to ParseIncoming() ByRef, but I'd rather not do that for every single procedure that needs to use it if I can help it, I'd much rather "Settings" just be a global thing that all of the files in my project can access.
Thanks for help up to this point, and for the future help I'm sure I'll be given :-)
-Brandon
PS. this line:
Friend Settings As New LocalSettings
from Plugin.vb, I've tried making that Public as well before it was Friend, to no avail
Re: Question about Scope, I'm a bit confused.
Here's a quick run down of the different levels of access available:
- Public
Available to all objects inside an assembly and outside an assembly. - Friend
Same as Public, however objects outside an assembly cannot access them. - Protected
Same as private except it is visible to a derrived class when using inheritance. Can also be coupled with the Friend modifier. - Private
Only available to the object that holds it and anything lower.
So if you reference a class library from your application, you will only be able to access public properties/methods/values, not friend or anything lower.
The Friend modifier when used in an assembly can make a class visible to everything in the assembly except nothing outside the assembly, such as an internal worker class.
Private varies depending on where it is declared. If in say a form class, a variable is declared just inside the class, it is available to every method inside that class, however, if it is declared inside a method, it is only visible to that method.
Re: Question about Scope, I'm a bit confused.
Quote:
So, that's just a run down of the problem, I can pass the Settings object to ParseIncoming() ByRef, but I'd rather not do that for every single procedure that needs to use it if I can help it, I'd much rather "Settings" just be a global thing that all of the files in my project can access.
I'm not sure I agree with your design decision, but it's not my project, so my approval isn't necessary. :) :)
I think you should get what you want by declaring your Settings object as Public in the module itself.
VB Code:
Module Parsing
Public Settings As LocalSettings
Public Sub ParseIncoming(ByVal Line As String)
... Here is where the problem comes in, I cannot access ...
... the Plugin class's instance of the LocalSettings class ...
... (called Settings) ...
Settings.SomeVal = 2 'This line fails, "Settings is not declared"
End Sub
End Module
That should allow the Settings object to be visible pretty much everywhere in the assembly. I'm not sure why "Friend" didn't accomplish this; perhaps it's an aspect of the way the project is namepsaced.
Re: Question about Scope, I'm a bit confused.
Quote:
I'm not sure I agree with your design decision, but it's not my project, so my approval isn't necessary.
What would you do differently? I realize I'm still fairly new, I always welcome criticism :-)
Re: Question about Scope, I'm a bit confused.
From the code you've posted, it appears as though the module is probably unnecessary. You've got a method in your Plugin class that does nothing but call another method:
VB Code:
Public Sub Parse(ByVal line As String)
ParseIncoming(line)
End Sub
I'd just take the code out of the Parsing module and put it in the Parse() method. Eliminate the module altogether (not to mention the pesky problem with the settings class).
Re: Question about Scope, I'm a bit confused.
That was my fault, hehe. The Parse() method of the main Plugin class contains a few other things as well, and this ParseIncoming() procedure is going to be fairly large, and connected to other procedures which will be in Parsing module as well. My intentions were mainly to keep all of the related procedures in a nice group by themselves, hence the module. Thinking about it now though, couldn't I make the Parsing module a class, and inherit it in the Plugin class, giving all of the plugin methods direct access to all of my parsing functions?
Here is another question as well, if I were to move the declaration for the settings object into the module itself, would multiple instances of the Plugin class get confused as to which they should be using?
For example, if 2 instances of the main application were loaded on the client computer, and both instances had this plugin loaded (and thus both would need a seperate Settings class instance), would having the Settings object declared in the module itself cause any conflict problems between the two instances of the application/plugin class?
Edit: Also, the ParseIncoming() procedure will be run in a different thread, due to the complexity of it, so having all of it's code directly in the Parse method probably won't work, since I'm not able to tell the running application to execute the Parse() method in a different thread, at least as far as I know.