473,569 Members | 2,652 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Multilayer applications

Hi,

People, I'd like to get some statistics about who and how writes a
multilayer applications.

We're having at least a few layers:

1. Representation layer, i.e. GUI.
2. Business logic layer.

What else? A data layer working with database, datasets etc.? Does anybody
separates this layer of it's easier to combine the last one with the
business logic layer? What are PROs and CONTRAs?

Another one question - we can get the DataSet from the database, then parse
it into our custom objects and work with objects. But I like to work with
DataSets directly where I see that it brings me some advantage, for example
it's the most useful solution to show the data in a DataGrid or in a
DataTable then I get my own object and fill up the DataGrid manually.

Can anybody write just a few words how he works with Web Applications for
example, the structure of the project, etc.?

Does anybody save the SQL queries into a separate file and makes a separate
data layer just to work with the database? Or basically all are preferring
to work at the business logic layer?

Thanks,
Dmitri

Nov 16 '05 #1
16 1960
SP
"Just D" <no@spam.please > wrote in message
news:qFiMc.1660 0$Zr.3254@okepr ead01...
Hi,

People, I'd like to get some statistics about who and how writes a
multilayer applications.

We're having at least a few layers:

1. Representation layer, i.e. GUI.
2. Business logic layer.

What else? A data layer working with database, datasets etc.? Does anybody separates this layer of it's easier to combine the last one with the
business logic layer? What are PROs and CONTRAs?
I generally separate it and reference it from the business layer. This keeps
you from being able to make the direct database calls from your GUI.
Another one question - we can get the DataSet from the database, then parse it into our custom objects and work with objects. But I like to work with
DataSets directly where I see that it brings me some advantage, for example it's the most useful solution to show the data in a DataGrid or in a
DataTable then I get my own object and fill up the DataGrid manually.
Stick with your custom objects and use datareaders. In time you will become
frustrated with the limitations of datasets in most situations.
Can anybody write just a few words how he works with Web Applications for
example, the structure of the project, etc.?
Not sure what you want here. A few pointers on web apps in general. Keep the
GUI simple. Try not to make a "Windows" app in your browser. Avoid view
state and session state as much as possible. Use hidden variables or
parameters as your WinForms equivalent of "static" variables.
Does anybody save the SQL queries into a separate file and makes a separate data layer just to work with the database? Or basically all are preferring
to work at the business logic layer?


Yes. My personal favorite is to use code generation to create all the
database methods (using SQLXML and XSLT). You end up with methods like
IDataReader MySelectStoredP rocedure(int parameter1, string parameter2)
{
// the code that returns a datareader
}

created automatically for every stored procedure.

SP
Nov 16 '05 #2
Hi,

Thanks for the answer.
I generally separate it and reference it from the business layer. This
keeps
you from being able to make the direct database calls from your GUI.
I supposed that GUI and the busuness logic layer are different instances.
Yes, that makes sense to separate them but how much it should be done. I saw
later in this message that you prefer to use the stored procedures instead
of embedded text queries. Is it true? I use Sql Queries from my business
layer but I wrote a SqlWrapper class library and I just send these queries
there and get the DataSets back.
Stick with your custom objects and use datareaders. In time you will
become
frustrated with the limitations of datasets in most situations.
Hm, if I need just to get some data and show it on the DataGrid then why
should I use my own custom object instead of a DataSet, it's easier to bind
an existing object to the DataGrid and enjoy. Am I right or not? Or you
parse all DataSets and create your own custom class then expose it? In all
other cases it's more convenient to use my own classes to work with data, I
know that.
Keep the GUI simple. Try not to make a "Windows" app in your browser.
Avoid view
state and session state as much as possible. Use hidden variables or
It's not always easy to go this way. Sometimes I use the same page to show
something and to edit something. It's my boss requirement. That's why I need
the page status, just to switch between page modes and it works fine.
parameters as your WinForms equivalent of "static" variables.
Yes, I found this trick, but sometimes these hidden variables are visible if
you save the page from your browser and that's not good. I saw many examples
when I was trying to save some page just to remember about the transaction
and I was getting a whole bunch of variables, hidden in a usual mode, but
visible in saved mode. That's funny, but not critical.
Yes. My personal favorite is to use code generation to create all the
database methods (using SQLXML and XSLT). You end up with methods like
Do you always use the Stored Procedures and never an implemented SQL code?
IDataReader MySelectStoredP rocedure(int parameter1, string parameter2)
{
// the code that returns a datareader
}
created automatically for every stored procedure.


I saw one solution where all SQL queries have been stored into external XML
file. I don't see that this approach is very good but it exists. From my
point of view it's much better to use a business layer to work with queries.
Maybe I'm wrong.

The main reason why I don't like this way - I can't use these class
libraries from Windows Application, because all these queries will be shared
as a simple text file. There is no security at all.

So how many layers you use?

1. GUI.
2. Business logic layer.
3. Database access layer.

Correct?

Are you having all your queries stored on the database as SPs?

Thanks,
Dmitri

Nov 16 '05 #3
My two bits:

there is a difference between a layer on one machine and creating
independent objects on multiple networked systems. I'm refraining my
comments to the idea of a layer of classes, all implemented in a single
solution, and deployed to a single machine. I can discuss the other, but
that doesn't appear to be the topic in question.

I usually have a low level data object of some kind, just to isolate my code
from the calls to ADO.NET... mostly because I don't trust that the ADO
interface itself won't change. I add on other classes to form the data
layer. The logic for connecting to the database, and the logic for getting
the data into the right entities, is all handled in the data layer objects
(which may be quite a few classes).

The business objects layer does not know the following:
--- whether data is accessed using SQL statements or stored proces
--- the names of the stored procedures, or the names of the tables
themselves.
--- when to create a transaction and when to commit it
--- where to get the connection string, and what to do if the login fails
--- how to manage the connection object, or whether the database is
connected
--- what version of MDAC is installed :-)
--- what foreign key column has to be copied to a dependent table row
when it is created
--- whether primary key values are mnemonic, auto-number, or
uniqueidentifie r (GUID), and who assigns them.

It is OK if the business layer knows the following...
--- that data is stored in tables, as long as the BL doesn't need to refer
to the actual table names
--- that the data is stored in a SQL Server RDBMS (that's pretty specific,
but I'm willing to live with it)
--- the names and data types of the columns
--- the values for the Primary Keys

Other people may want to partition these responsibilitie s differently, and
I'm not saying that this list, which usually works for me, will work for
anyone else, or even that it always works for me in every possible case.
That depends on the application.

I have some other rules of thumb:
--- write no code that obscures good functionality already provided in
the framework Extension is OK. Hiding for the sake of hiding is harmful.
--- I will write a defect for every 20 lines of code (on a really good
day). If I don't want to create job security, I will write as little code
as possible.
--- Use design patterns to hide the details of implementing an object, so
that objects that have the same
attributes can be substituted for each other (my loose
interpretation of the Liskov Substitution Principle)
--- Minimize Coupling. Maximize Cohesion. Harder to do than it sounds.

Personally, I have no problem passing around data in DataSet objects. I
personally have not become disenchanted with them, but I don't pretend to
use every feature. If I did, I imagine I would join the chorus of folks who
can find fault with this generic disconnected data object. I also have no
problem using a DataReader, and copying the data into a collection of
DataRow objects that I pass around.

The U/I layer is more than the ASP.NET web pages. I use code behinds
exclusively. In addition, there is nearly no code in the code behind. Only
enough to create an object that is used by the page and to call that object.
This layer of U/I objects is still part of the U/I layer. This is done so
that I can write NUnit tests for the U/I objects without having to call the
Web pages themselves to test the application.
My rules of thumb for the U/I management layer:
--- no web or windows controls may be passed as a parameter to the U/I
object layer.
--- validation happens in the U/I management layer by calling the
business object layer. It does not happen in the
code behind and, as much as possible, it does not happen in the U/I
management code itself... it's a pass through.
--- If I must hard-code a list of values for the web pages, the list is
specified in an object in the U/I management layer, not in the web page.
--- Use the O/S to provide security services as much as possible. Do not
store passwords in the database, due to the
complexities of handling encrypted in a secure manner. (This also
goes back to writing as little code as I can).

Business rules live in the BL. The rules do, and the formulas do.
Constants, however, and easily isolated hard-coded strings, all live in the
config files. Note: all layers can use the config files. There is nothing
at all wrong with placing the names of your stored procedures in the config
files as well as the business rule constants. (For example, if I have a
rule that says "when an invoice goes unpaid for 30 days, send a message to
the exchange alias "WarnAccounting ", then I will store the number 30 and the
alias "WarnAccounting " in the config file, along with the name of an XSL
template that will be used to generate the layout of the e-mail itself).

I hope this helps.

--- Nick Malik

"Just D" <no@spam.please > wrote in message
news:eblMc.1661 9$Zr.11652@okep read01...
Hi,

Thanks for the answer.
I generally separate it and reference it from the business layer. This
keeps
you from being able to make the direct database calls from your GUI.
I supposed that GUI and the busuness logic layer are different instances.
Yes, that makes sense to separate them but how much it should be done. I

saw later in this message that you prefer to use the stored procedures instead
of embedded text queries. Is it true? I use Sql Queries from my business
layer but I wrote a SqlWrapper class library and I just send these queries
there and get the DataSets back.
Stick with your custom objects and use datareaders. In time you will
become
frustrated with the limitations of datasets in most situations.
Hm, if I need just to get some data and show it on the DataGrid then why
should I use my own custom object instead of a DataSet, it's easier to

bind an existing object to the DataGrid and enjoy. Am I right or not? Or you
parse all DataSets and create your own custom class then expose it? In all
other cases it's more convenient to use my own classes to work with data, I know that.
Keep the GUI simple. Try not to make a "Windows" app in your browser.
Avoid view
state and session state as much as possible. Use hidden variables or
It's not always easy to go this way. Sometimes I use the same page to show
something and to edit something. It's my boss requirement. That's why I

need the page status, just to switch between page modes and it works fine.
parameters as your WinForms equivalent of "static" variables.
Yes, I found this trick, but sometimes these hidden variables are visible

if you save the page from your browser and that's not good. I saw many examples when I was trying to save some page just to remember about the transaction
and I was getting a whole bunch of variables, hidden in a usual mode, but
visible in saved mode. That's funny, but not critical.
Yes. My personal favorite is to use code generation to create all the
database methods (using SQLXML and XSLT). You end up with methods like
Do you always use the Stored Procedures and never an implemented SQL code?
IDataReader MySelectStoredP rocedure(int parameter1, string parameter2)
{
// the code that returns a datareader
}
created automatically for every stored procedure.


I saw one solution where all SQL queries have been stored into external

XML file. I don't see that this approach is very good but it exists. From my
point of view it's much better to use a business layer to work with queries. Maybe I'm wrong.

The main reason why I don't like this way - I can't use these class
libraries from Windows Application, because all these queries will be shared as a simple text file. There is no security at all.

So how many layers you use?

1. GUI.
2. Business logic layer.
3. Database access layer.

Correct?

Are you having all your queries stored on the database as SPs?

Thanks,
Dmitri

Nov 16 '05 #4
SP
"Just D" <no@spam.please > wrote in message
news:eblMc.1661 9$Zr.11652@okep read01...
Hm, if I need just to get some data and show it on the DataGrid then why
should I use my own custom object instead of a DataSet, it's easier to bind an existing object to the DataGrid and enjoy. Am I right or not? Or you
parse all DataSets and create your own custom class then expose it? In all
other cases it's more convenient to use my own classes to work with data, I know that.
This forces you to make sure the actual data is present in the dataset. Your
business object is not constrained in needing to contain
the actual "display" data, e.g Your Employee object has a EmployeeName and
DepartmentName properties. But
internally the Employee object only knows the Department key and is really
calling DepartmentsColl ection[key].DepartmentName to provide the
"display" data. Getting the same behavior from a dataset is not so easy. I
like the ability to make my business objects "self serving".
Keep the GUI simple. Try not to make a "Windows" app in your browser.
Avoid view
state and session state as much as possible. Use hidden variables or


It's not always easy to go this way. Sometimes I use the same page to show
something and to edit something. It's my boss requirement. That's why I

need the page status, just to switch between page modes and it works fine.
Any "sophistica ted" control will need ViewState in order to provide the
events necessary to handle multiple edits etc.
But selecting an employee from a dropdown list of 1000 employees can be
handled with some javascript and a hidden field.
Yes. My personal favorite is to use code generation to create all the
database methods (using SQLXML and XSLT). You end up with methods like


Do you always use the Stored Procedures and never an implemented SQL code?


Unless I need to provide custom querying then stored procedures cover all
the bases. A data mapper co-ordinates between the business
classes and the database layer. It is "add new, delete removed, update
dirty".
I saw one solution where all SQL queries have been stored into external XML file. I don't see that this approach is very good but it exists. From my
point of view it's much better to use a business layer to work with queries. The main reason why I don't like this way - I can't use these class
libraries from Windows Application, because all these queries will be shared as a simple text file. There is no security at all.


My method does not distribute the XML file. It uses this metadata to
generate a database class and business object abstract classes.
I change the XSLT around to suit the methods I want for the particular
project. Sometimes I pass the business object to the
stored procedure method and let it get the values it needs from the object
rather than populating a long list of
parameters.

SP
Nov 16 '05 #5
Hi SP,

Your XSLT data layer generater sounds very interesting.
Where can I find out more? Did you buy it? Download it?

If you wrote it, could you put an article on codeproject?

It sounds pretty cool.

--- Nick

"SP" <egatsecneserp( reverse)@hotmai l.com> wrote in message
news:e8******** ******@TK2MSFTN GP12.phx.gbl...
"Just D" <no@spam.please > wrote in message
news:eblMc.1661 9$Zr.11652@okep read01...
Hm, if I need just to get some data and show it on the DataGrid then why
should I use my own custom object instead of a DataSet, it's easier to bind
an existing object to the DataGrid and enjoy. Am I right or not? Or you
parse all DataSets and create your own custom class then expose it? In all
other cases it's more convenient to use my own classes to work with data, I
know that.
This forces you to make sure the actual data is present in the dataset.

Your business object is not constrained in needing to contain
the actual "display" data, e.g Your Employee object has a EmployeeName and
DepartmentName properties. But
internally the Employee object only knows the Department key and is really
calling DepartmentsColl ection[key].DepartmentName to provide the
"display" data. Getting the same behavior from a dataset is not so easy. I
like the ability to make my business objects "self serving".
Keep the GUI simple. Try not to make a "Windows" app in your browser.
Avoid view
state and session state as much as possible. Use hidden variables or
It's not always easy to go this way. Sometimes I use the same page to show something and to edit something. It's my boss requirement. That's why I

need
the page status, just to switch between page modes and it works fine.


Any "sophistica ted" control will need ViewState in order to provide the
events necessary to handle multiple edits etc.
But selecting an employee from a dropdown list of 1000 employees can be
handled with some javascript and a hidden field.
Yes. My personal favorite is to use code generation to create all the
database methods (using SQLXML and XSLT). You end up with methods like


Do you always use the Stored Procedures and never an implemented SQL

code?
Unless I need to provide custom querying then stored procedures cover all
the bases. A data mapper co-ordinates between the business
classes and the database layer. It is "add new, delete removed, update
dirty".
I saw one solution where all SQL queries have been stored into external

XML
file. I don't see that this approach is very good but it exists. From my
point of view it's much better to use a business layer to work with

queries.
The main reason why I don't like this way - I can't use these class
libraries from Windows Application, because all these queries will be

shared
as a simple text file. There is no security at all.


My method does not distribute the XML file. It uses this metadata to
generate a database class and business object abstract classes.
I change the XSLT around to suit the methods I want for the particular
project. Sometimes I pass the business object to the
stored procedure method and let it get the values it needs from the object
rather than populating a long list of
parameters.

SP

Nov 16 '05 #6
Hi,
This forces you to make sure the actual data is present in the dataset.
Your
That's only one call to your SqlWrapper like:

public bool IsDataSetOK(Dat aSet ds)
{
return ((ds!=null)&&(d s.Tables.Count> 0)&&(ds.Tables[0].Rows.Count>0)) ;
}
business object is not constrained in needing to contain
the actual "display" data, e.g Your Employee object has a EmployeeName and
Not exactly, it depends what data do you need at this moment, but you easily
can add a column manually and add some calculated data to this column.
DepartmentName properties. But
internally the Employee object only knows the Department key and is really
calling DepartmentsColl ection[key].DepartmentName to provide the
"display" data. Getting the same behavior from a dataset is not so easy. I
like the ability to make my business objects "self serving".
Not so easy?! Why? What about sql queries (and maybe subqueries) providing a
comprehensive information? You can join on this DepartmentKey a few tables
getting all required stuff into additional DataSet column and reflect this
column in the DataGrid automatically just from one database call, it's
easier than retrieve the whole information in two or more datasets, then
make a foreach loop every one when you need to compare two or more tables.
In a SQL solution everyting should be solved by SQL engine itself.
But selecting an employee from a dropdown list of 1000 employees can be
handled with some javascript and a hidden field. Yes, but these is only one solution, You can use LIKE '%!@!#!@#%' in your
queries to get only required records by mask, you can sort them by the
alphabet and return only required group, there are many different methods.
You also can use browse feature of SQL queries, etc.
My method does not distribute the XML file. It uses this metadata to
generate a database class and business object abstract classes.
I change the XSLT around to suit the methods I want for the particular
project. Sometimes I pass the business object to the
stored procedure method and let it get the values it needs from the object
rather than populating a long list of parameters.


That's interesting.

Thanks,
Dmitri

Nov 16 '05 #7
SP
"Nick Malik" <ni*******@hotm ail.nospam.com> wrote in message
news:5iyMc.1546 85$%_6.136437@a ttbi_s01...
Hi SP,

Your XSLT data layer generater sounds very interesting.
Where can I find out more? Did you buy it? Download it?

If you wrote it, could you put an article on codeproject?

It sounds pretty cool.


The basis of it was from an article in msdn magazine August 2003.
http://msdn.microsoft.com/msdnmag/is...n/default.aspx
I tweaked the query that generated the XML metadata and I enhance the XSLT
file
on a per project basis. It eliminate a lot of repetitive data access layer
coding and
immediately reflects any added or changed stored procedures.
Nov 16 '05 #8
SP
"Just D" <no@spam.please > wrote in message
news:8iyMc.7643 $BX.720@lakerea d08...
business object is not constrained in needing to contain
the actual "display" data, e.g Your Employee object has a EmployeeName and

Not exactly, it depends what data do you need at this moment, but you easily can add a column manually and add some calculated data to this column.
Exactly my point, you need to handle that particular situation "manually". I
prefer "automatic" .
DepartmentName properties. But
internally the Employee object only knows the Department key and is really calling DepartmentsColl ection[key].DepartmentName to provide the
"display" data. Getting the same behavior from a dataset is not so easy. I like the ability to make my business objects "self serving".


Not so easy?! Why? What about sql queries (and maybe subqueries) providing

a comprehensive information? You can join on this DepartmentKey a few tables
getting all required stuff into additional DataSet column and reflect this
column in the DataGrid automatically just from one database call, it's
easier than retrieve the whole information in two or more datasets, then
make a foreach loop every one when you need to compare two or more tables.
In a SQL solution everyting should be solved by SQL engine itself.


I tend to disagree with this. At a certain point the complexity of what you
are doing in the
SQL engine increases and crosses into the business rules.

In the example I gave you would have a grid with the EmployeeName and their
Department.
If I want to be able to change the department using a dropdown, how easy is
that to implement using your datasets.
Once you use a join to create a dataset you can not use the dataadapter to
persist the
changes made in that dataset directly back to the database. This was the one
thing that was most frustrating
about datasets.
But selecting an employee from a dropdown list of 1000 employees can be
handled with some javascript and a hidden field.

Yes, but these is only one solution, You can use LIKE '%!@!#!@#%' in your
queries to get only required records by mask, you can sort them by the
alphabet and return only required group, there are many different methods.
You also can use browse feature of SQL queries, etc.


I was refering to this as something that can be handled "quickly" by using
viewstate on the
dropdown which will slow down the page and the postback, or can be handled
with
a hidden field and javascript and will make a much faster loading webpage.

SP
Nov 16 '05 #9
Hi,
I tend to disagree with this. At a certain point the complexity of what
you
are doing in the SQL engine increases and crosses into the business rules.
Ok, what are your rules? Do you just get as simple data as possible and do
the rest on the code? But why the whole world is still using the joins,
table relations etc.? What are advs./disadvs. of both solutions?
If I want to be able to change the department using a dropdown, how easy
is
that to implement using your datasets.
Once you use a join to create a dataset you can not use the dataadapter to
persist the
changes made in that dataset directly back to the database. This was the
one
thing that was most frustrating
about datasets.


Stop, are you allowing all changes made in the same DataGrid? I usually make
a separate dialog to make these changes. I don't ask about disadvantages,
I'm just wondering...

Thanks,
Dmitri

Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2266
by: Constandinos Mavromoustakis | last post by:
CFP: CLADE 2004-Challenges of Large Applications in Distributed Environments ------------------------------------------------- PhD student - Dept.Informatics at Aristotle University of Thessaloniki URL-> http://agent.csd.auth.gr/~cmavrom -------------------------------------------------- -------------------------CLADE...
1
1689
by: Tom Q | last post by:
A user has multiple applications running on his/her PC and I want to create a broker component or service that is shared among the multiple apps. Each time an application changes a record it notifies the broker and the broker in turn notifies the other applications so they can take appropriate actions. Any one app may send a string data to...
3
3246
by: MrCAD | last post by:
well this is my first post in here..and I need some help regarding multilayer tiff file format. Any link/references would really help me to progress my project. thanks alot in advance MrCAD
385
17008
by: Xah Lee | last post by:
Jargons of Info Tech industry (A Love of Jargons) Xah Lee, 2002 Feb People in the computing field like to spur the use of spurious jargons. The less educated they are, the more they like extraneous jargons, such as in the Unix & Perl community. Unlike mathematicians, where in mathematics there are no fewer jargons but each and every...
6
6932
by: Ray | last post by:
DB2 V7.2 Is it possible to list applications connected to a node by Auth ID? Is it possible to force applications connected to a node by Auth ID or am I forced to use App. Handle? Thanks, Ray
5
6677
by: Prakash T. | last post by:
Dear friends, This is Prakash from in India at tamilnadu. I am a MCA Student. Please answer the Que: Mention the type of applications which can be developed using C language? Thanks and Regards Prakash T. Karur
1
983
by: imonline | last post by:
Hi, I want to make a multilayer video using .net 2005. Does any body has any idea on this? Any help is highly appreciated. Thanks, Nis
0
7700
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8125
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7676
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
1
5513
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5219
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3642
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1221
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
938
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.