12 Replies - 494 Views - Last Post: 02 February 2012 - 01:54 PM Rate Topic: -----

Topic Sponsor:

#1 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Passing data back from a class library

Posted 28 January 2012 - 11:03 AM

Evening. I appreciate this is probably a very simple question but i wanted to make sure what i was doing was correct so i didnt have to unlearn a bad habit.

i have the following code:
        string initial;
        string final;

        public bool BothPopulated()
        {
            //Initial > Final Value
            if ((int.Parse(initialValueTxt.Text)) > (int.Parse(finalValueTxt.Text)))
            {
                MessageBox.Show("Initial Value > Final Value." + Environment.NewLine + "Please adjust so that the Initial Value < Final Value.", "Input Error");

                initialValueTxt.Focus();
                return false;
            }
            //Both Contain correct values
            else
            {
                initial = initialValueTxt.Text;
                final = finalValueTxt.Text;
                return true;
            }
        }



the string variables will be in the form1 class. I want to place the method BothPopulated() in a class library. In the class library, i create the variables initial and final of type string (both priavte), and then have public Getters which return their value to the form1 class?

Is this correct or not?

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Passing data back from a class library

#2 RexGrammer  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 152
  • View blog
  • Posts: 664
  • Joined: 27-October 11

Re: Passing data back from a class library

Posted 28 January 2012 - 11:24 AM

So you mean something like this:

public void BothPopulated(string first, string second)
{
   //...
   return true;
   //...
   return false
}


?

And then return access some other variables also stored in the .dll?

Well you could return a custom class from the method containing both variables and the true/false indicator. This could solve your problem in a more elegant way.

NOTE: Never pass controls to a method that handles some input in a dll. And don't use GUI objects in those methods. You should handle the output of the method in the form.
Was This Post Helpful? 1
  • +
  • -

#3 tlhIn`toq  Icon User is online

  • WillMyCodeWork = !FailedWhenYouTriedIt;
  • member icon

Reputation: 3290
  • View blog
  • Posts: 6,895
  • Joined: 02-June 10

Re: Passing data back from a class library

Posted 28 January 2012 - 11:38 AM

It is rather uncommon to store values back INTO a library. So my first thought is to ask why you feel you need to do this. If you're using the library as a mechanism for passing values between applications or between classes then I would recommend re-evaluating your design because that's not really an accepted way to do it.

One of the big problems with storing a value in the DLL is that it makes the DLL tightly bound to that one thread. What happens when several classes or applications are trying to use the DLL? Application/thread #1 stores a value for later retrieval. Then Application/threaD #2 does it. When Application/thread #1 gets this value back it is NOT what it expected. In other words this technique is not what we call 'thread safe'.

So I would consider this a bad habit to get into.
Was This Post Helpful? 1
  • +
  • -

#4 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Passing data back from a class library

Posted 28 January 2012 - 11:54 AM

First, thanks to both of you for replying.

I have a section of the code below which i will split into the sections i want to be in the Form and the Class Lib.

General jist is as follows:

1) 2 x TextBoxes on the form
2) 1 x Class Lib which checks/verifies the inputs (5 possible combinations)
3) 1 x Class Lib which Uploads The DataTable using the inputs from the 1st Class Lib.


Form

          
        private void bntLoad_Click(object sender, EventArgs e)
        {
            if (ValuesAreValid())
            {
                UploadData();    //This will be in a separate Class Library
            }          
        }




Class Library


        public bool ValuesAreValid()
        {
            //Both Initial & Final contain numbers
            if (initialValueTxt.Text != "" && finalValueTxt.Text != "")
            {
                bool bool1 = BothPopulated();
                return bool1;
            }

            //Both Initial & Final are empty
            if (initialValueTxt.Text == "" && finalValueTxt.Text == "")
            {
                initialValueTxt.Text = "0";
                finalValueTxt.Text = "10";      // ADJUST TO IT CONTAINS MAX VALUE OF CSV FILE FROM CSVCHECKER
                return true;
            }

        //One Value is not declare
        return OneEmpty();
        }

//The Following are just methods im using so ValuesAreValid() is more readable



        public bool BothPopulated()
        {
            //Initial > Final Value
            if ((int.Parse(initialValueTxt.Text)) > (int.Parse(finalValueTxt.Text)))
            {
                MessageBox.Show("Initial Value > Final Value." + Environment.NewLine + "Please adjust so that the Initial Value < Final Value.", "Input Error");

                initialValueTxt.Focus();
                return false;
            }
            //Both Contain correct values
            else
            {
                initial = initialValueTxt.Text;
                final = finalValueTxt.Text;
                return true;
            }
        }

        public bool OneEmpty()
        {
            //Initial not declared
            if (initialValueTxt.Text == "")
            {
                initial = "0";
                final = finalValueTxt.Text;
                return true;
            }
            //Final not declared
            else
            {
                initial = initialValueTxt.Text;
                final = "10";        // ADJUST TO IT CONTAINS MAX VALUE OF CSV FILE FROM CSVCHECKER
                return true;
            }
        }





Note: the way the code is atm it does work in a single class but i want to learn how to use Class Libraries correctly.

Note2: I havent included the code for the 2nd class lib

Thanks again for your help, i really appreciate it.

This post has been edited by scolty: 28 January 2012 - 11:55 AM

Was This Post Helpful? 0
  • +
  • -

#5 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Passing data back from a class library

Posted 28 January 2012 - 12:07 PM

Re Rex: Yes what you have it what im wanting but in the above code, you can see there are situations where i need to assign values to the two inputs and then pass them back to the form as these are then used in the UploadData class library so it knows which rows it needs to upload.

I havent experimented with passing a custom class back? Do you have a link to a good example?


Re Tlhin: I havent written it so that i need to store the value in it permanently (atleast i dont think so) but i need to be able to pass values into. Return multiple values back from it and pass some of these into the next class lib.

Yeah i completely agree with you regarding the problem of storing a value in the class lib but what im proposing wouldnt be a problem in that respect?? Or can a class lib be called on one thread while a second thread is already half way through using the same lib ( this is just for future knowledge since this wont be using multi threading)

Thanks again guys
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is online

  • WillMyCodeWork = !FailedWhenYouTriedIt;
  • member icon

Reputation: 3290
  • View blog
  • Posts: 6,895
  • Joined: 02-June 10

Re: Passing data back from a class library

Posted 28 January 2012 - 12:09 PM

View Postscolty, on 28 January 2012 - 12:54 PM, said:

General jist is as follows:

1) 2 x TextBoxes on the form
2) 1 x Class Lib which checks/verifies the inputs (5 possible combinations)
3) 1 x Class Lib which Uploads The DataTable using the inputs from the 1st Class Lib.

Note: the way the code is atm it does work in a single class but i want to learn how to use Class Libraries correctly.


It sounds like this makes the library so tightly dependent on the form there is little point in it being library. Realistically, could these functions be used across several of your programs? Doesn't sound like it. And that is the point of shared libraries. Just because you can make a library function doesn't mean you have to, or that it is the best thing to do. If the method is not really designed to be shared because it has such a singular purpose then don't share it.

Instead of storing values in the library... pass the values as parameter to the methods and get a value back.

In this really simplistic example we have a property for an email address. When the user enters an address we send their input to a method in the DLL for validation and get a bool back. Nothing is stored in the DLL.

string ClientEmailAddy{ get; set;}

bool result = dllIsValidEmailAddress(ClientEmailAddy);
if (!result) GetEmailAddyFromUser();

Was This Post Helpful? 1
  • +
  • -

#7 tlhIn`toq  Icon User is online

  • WillMyCodeWork = !FailedWhenYouTriedIt;
  • member icon

Reputation: 3290
  • View blog
  • Posts: 6,895
  • Joined: 02-June 10

Re: Passing data back from a class library

Posted 28 January 2012 - 12:18 PM

View Postscolty, on 28 January 2012 - 01:07 PM, said:

but i need to be able to pass values into. Return multiple values back from it and pass some of these into the next class lib.


Frankly I think *need* is incorrect. More likely to say that's the idea so far. But honestly this already sounds like bad architecture. Bad design can only lead to problems. When you have 5,000 lines of code centered around and dependent on this scheme and you realize its a bad scheme, you're sunk!

View Postscolty, on 28 January 2012 - 01:07 PM, said:

Yeah i completely agree with you regarding the problem of storing a value in the class lib but what im proposing wouldnt be a problem in that respect?? Or can a class lib be called on one thread while a second thread is already half way through using the same lib ( this is just for future knowledge since this wont be using multi threading)


Absolutely they can! They are SHARED. They don't use and tie up the lib as a whole. They make an instance of the method they need and use it. So you certainly can have 3 threads all make their own instance of the ValidateThisString() method at the same time. Or one application uses ValidateThisString() while another is accesses GetUserNames()

To summarize: You asked if this was a bad habit. I'm telling you it is more than bad, its dangerous. It can only lead to trouble.

Libraries and the methods within are meant to be descrete sharable methods that take parameters in and pass results out. Period. They are not shoe boxes to be used to store values: That's what your application is for.

I can't say it any more plainly than this: Redesign your application so you don't do this. Don't make your libraries in this manner.
Was This Post Helpful? 1
  • +
  • -

#8 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Passing data back from a class library

Posted 02 February 2012 - 06:17 AM

Im not sure i fully follow this. If someone could point out if the follow is correct id appreciate it.

1) dont pass winform objects into a class lib.
2) dont declare any variables at class scope.
3) dont declare a variable within a method and store a formal parameters value in it?

when i create an instance of a class lib in my application, what actually happens memory wise? As far as i was aware, when i created a normal object, a discrete object was created in memory. If another is created afterwards a second discrete object is created.

is that correct?

thanks.

EDIT: assuming i need it to be thread safe.If it didnt have to be then i could forget about all 3 points?

This post has been edited by scolty: 02 February 2012 - 07:01 AM

Was This Post Helpful? 0
  • +
  • -

#9 RexGrammer  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 152
  • View blog
  • Posts: 664
  • Joined: 27-October 11

Re: Passing data back from a class library

Posted 02 February 2012 - 09:35 AM

1) Correct
2) More or less (there are situations where you have to do this). It's just important that you don't store some non-class-function-related variables in the class scope.
3) You can do this to get some result. Again it's important that you don't store irrelevant (to the class's function) variables in the class scope

When you declare a class in your code a piece of memory that is just enough to hold your instance is reserved. Then when you instantiate it, it fills that piece of memory with data which you later change.

About your edit: No you shouldn't forget about these three points, those are some general design rules.

And consider making your class static. If you don't need to rely on instances then you can make it static and make all methods in it static. That way you will gain efficiency and reduce memory consumption.
Was This Post Helpful? 1
  • +
  • -

#10 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon

Reputation: 3129
  • View blog
  • Posts: 5,402
  • Joined: 08-June 10

Re: Passing data back from a class library

Posted 02 February 2012 - 12:57 PM

Quote

When you declare a class in your code a piece of memory that is just enough to hold your instance is reserved. Then when you instantiate it, it fills that piece of memory with data which you later change.


That's not actually true. Allocation doesn't happen until instantiation. When you declare the variable, a block of memory large enough to hold a memory address is created on the stack. When you instantiate your class, a block of memory is allocated in the heap to hold the class, filled, and the address of it is assigned to the variable (back in the stack). That's why certain techniques such as lazy initialization are popular. In fact, one of the ways to create a Singleton relies on this. A simple static instance would be initialized immediately, but a proper singleton isn't initialized until the first time it's called.

As to storing class level variables, there's nothing wrong with it, when it makes sense to do so. Basically, if something describes the class, it makes sense to store it at the class level. Just an example, a database context class will store a connection string, a connection object, etc, at class level, because those things describe the instance of a class. It won't store things like queries at class level, because those describe actions rather than instances of the class.

Now, it can be argued that some of these things should be stored in properties, and I won't disagree in the case of one of my examples. However, sometimes it's important to store class-level information that shouldn't be visible outside the class itself. For instance, the DB Connection object. That's something that should never be used outside the class, and yet it'll be used consistently throughout the class itself. In that case, a property is relatively pointless, because it'd be a private get, private set property. There are times when that'd be useful, but for truly private variables, it's often good enough to make a private field instead of property.

Thread safety is one of those interesting issues. It's good to be thread-safe, of course. Crucial, if you're ever going to be using your components in a threaded manner. So it's always smart to code with that in mind. Typically, non-static classes are relatively threadsafe by themselves, since they don't rely on shared resources (all the resources belong to the class itself, and nothing else, so when a new class is made, it gets its own resources). Static classes and methods and properties are where you have to really be concerned about thread safety, because they are shared resources, and may be called simultaneously. Learn about "critical sections" and the lock keyword if you're interested in thread safety.
Was This Post Helpful? 1
  • +
  • -

#11 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Passing data back from a class library

Posted 02 February 2012 - 01:24 PM

Regarding the memory and classes, is it exactly the same for class libraries? I was confused with the following

Quote

Absolutely they can! They are SHARED. They don't use and tie up the lib as a whole. They make an instance of the method they need and use it. So you certainly can have 3 threads all make their own instance of the ValidateThisString() method at the same time.
as i had thought that was only the case with static methods (believe you said that above).

In light of the fact that its poor form to pass winform object into class libraries, is it possible to declare an event in the class library, and then subscribe to it in the main application where i can pass in winform objects?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Configuration;

namespace Storing_Connection_String
{
    public class LoadData
    {
        public event EventHandler<EventArgs> SecondaryEvent;

        public void ConnectNow(DataTable populatedDataTable, string dataTableName, int numberOfColumns, int numberOfRows, int batchSize, string methodPath)
        {
            string status = "";

            #region Read connection string from app.config
            .....
            #endregion

            try
            {
                using (SqlConnection cn = new SqlConnection(connectionString))
                {
                        #region Open connection 
                        //Open a connection to the database.
                        cn.Open();
                        #endregion Open connection

                        using (SqlTransaction transaction = cn.BeginTransaction())
                        {

                            #region Upload the datatable via SQLBulkCopy
                            using (SqlBulkCopy copy = new SqlBulkCopy(cn, SqlBulkCopyOptions.Default, transaction ))
                            {
                                //column map the required columns
                                for (int count = 0; count < numberOfColumns; count++)
                                {
                                    copy.ColumnMappings.Add(count, count);
                                }

                                //Table, in the database, to recieve the data.
                                copy.DestinationTableName = dataTableName;
                                copy.SqlRowsCopied += new SqlRowsCopiedEventHandler(TestMethod);    
                                copy.NotifyAfter = 2;
                                copy.BatchSize = batchSize;
                                copy.WriteToServer(populatedDataTable);
                            }
                            #endregion Upload the datatable via SQLBulkCopy
                        }
                }
            }
            #region Exception handling
            ...
            #endregion Exception Handling
        }
        public void TestMethod(object sender, SqlRowsCopiedEventArgs e)
        {
            EventHandler<EventArgs> TempHandler = this.SecondaryEvent;
            if (TempHandler != null) TempHandler(this, EventArgs.Empty);

        }
    }
}



i dont understand how to do this with the sqlrowscopied event in the above code.

For the record, im not sure the above is correct regarding this quote from MSDN which seems to suggest that i cant have this sqlrowscopied event and a transaction??(seems odd).

Quote

No action, such as transaction activity, is supported in the connection during the execution of the bulk copy operation, and it is recommended that you not use the same connection used during the SqlRowsCopied event. However, you can open a different connection.


Thanks Curtis

This post has been edited by scolty: 02 February 2012 - 01:39 PM

Was This Post Helpful? 0
  • +
  • -

#12 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon

Reputation: 3129
  • View blog
  • Posts: 5,402
  • Joined: 08-June 10

Re: Passing data back from a class library

Posted 02 February 2012 - 01:49 PM

"Shared" is a tricky word. He's not using it the same way I was. When I say "shared", I mean "static." (Actually, VB.NET's keyword for static is Shared).

Here's the thing: don't try to think of a library as something special. It's just organization. It's exactly the same as an executable project (like a console/winforms app), with one difference: it doesn't have a Main method, so it's not executable. Other than that, they're both .NET Assemblies, so they behave the same. DLLs are just a project to organize code into, a project that can't be run. Most of the other projects do have a way to be run, but they're still Assemblies. Code behaves the same way.

As to creating events in a class library, of course it's doable. tlhIn`toq has a tutorial (that I can't find at the moment) that describes how to make custom events. I'm sure he'll link it for you.

As to your last question, I'm afraid I don't know about the correctness of that code, because I've really never had to use bulk copy.
Was This Post Helpful? 1
  • +
  • -

#13 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Passing data back from a class library

Posted 02 February 2012 - 01:54 PM

Yeah, that makes more sense now.

Regarding the link, dont worry i already have it and Jason's one as well, its just something i dont seem to have a firm grasp of.

No worries, ill give it a shot n see what happens.

Thanks again.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1