Singleton Data Access Object (Dao) & SQL Helper Instance, Is here any Performance drawback? - data-access-layer

I need comments from Experts. I write my own SQL Helper Class to Communicate with DB.
Why I use it as because I try to
Encapsulate the Ado.Net logic.
Try to set a common standard for my developer in terms of DAL coding.
Flexible & Easy to use.
Same kind of code block for SQL Server/ Oracle / Access / Excel / Generic Database code block approach (SQL Server & Oracle) e.t.c.
Plug & Play or Reusable approach.
In terms of code optimization
This helper class or Assembly is CLS Compliant.
It pass Successfully by FxCop / Static Code Analysis.
I give you the sample Code Block (DAO). Please check bellow
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
#region include SQL Helper Namespace
using DBManager;
#endregion
#region include SQL Helper Namespace
using DBManager;
#endregion
namespace ContentManagementSystem.DataAccessLayer
{
/// <summary>
///
/// </summary>
public sealed class DaoContentOwner : DataAccessBase
{
#region CONSTRUCTOR
/// <summary>
///
/// </summary>
private DaoContentOwner()
{
GetInstance = new DaoContentOwner();
}
#endregion
//############################################# M E T H O D S ##########################
#region Retrieve Content Owner
/// <summary>
/// Retrieve Content Owner
/// </summary>
/// <returns></returns>
public static DataTable RetrieveContentOwner()
{
DataTable dt = null;
try
{
using (DBQuery dq = new DBQuery("stpGetContentOwner"))
{
dt = dq.ResultSetAsDataTable();
return dt;
}
}
catch (Exception)
{
throw;
}
finally
{
if (dt != null)
{
dt.Dispose();
}
}
}
#endregion
//############################################# P R O P E R T Y ########################
#region READ ONLY PROPERTY
/// <summary>
/// GetInstance of DaoContentOwner Class
/// </summary>
public static DaoContentOwner GetInstance { get; private set; }
#endregion
}
}
Justification:
"DataAccessBase" It is a Abstract class. Implement IDisposable Interface.
"DBQuery" is SQL Helper for SQL Server Only. It is a Sealed class. It is takes T-SQL / SP according to needs. Open an close database connection. No need to handel any thing by developer.
Why I make DAO Singleton Class, Because my all the methods withing DAO is a static method. I order to memory optimization I make it Singleton. It is also a design Principal.
Note: Needs comments. Whether need to change in the design or some thing is wrong that need to correct.

Personally I would go with:
DALFileItem dalF = new DALFileItem(DSN);
List<FileItem> list = dalF.GetAll("");
Allows accessing multiple databases, without making DSN static member.
In multithreaded environment only one thread will have access to the static method.
More object oriented: you can add interfaces, base classes and generics easier that way.

Related

Implementing IDisposable for WCF service client - Am I doing this right?

I want to safely dispose my WCF client, but I'm not sure if I am implementing IDisposable in the right spot.
I added code to implement IDisposable in the service client inside the Reference.vb file that was created when I added the WCF service as a service reference:
Partial Public Class Service1Client
Inherits System.ServiceModel.ClientBase(Of DataConversionService.IService1)
Implements DataConversionService.IService1, IDisposable
Public Sub New()
MyBase.New
End Sub
'skipping constructors with multiple parameters...
Public Sub Dispose() Implements IDisposable.Dispose
Try
If State <> CommunicationState.Faulted Then
Close()
End If
Finally
If State <> CommunicationState.Closed Then
Abort()
End If
End Try
End Sub
Did I add this in the right spot? When debugging, I wasn't able to hit my breakpoint in the Dispose sub.
Any help is appreciated!
You were close. Firstly, you shouldn't change that Reference.vb file since it will be overwritten when the service definition gets updated and changing that file is not a good practice.
What you can do instead is using Proxy Pattern. The Proxy will be used to call the methods in services and manage the connection state etc. I will write in C# since I don't know VB but you'll get the idea. I will simplify this as much as I can.
The interface of Proxy class might look like this:
public interface IProxy
{
/// <summary>
/// Execute call to service method
/// </summary>
/// <typeparam name="TBusiness">Service interface</typeparam>
/// <typeparam name="TResult">Service method return type</typeparam>
/// <param name="call">Service method</param>
/// <returns>Returns what service method returns</returns>
TResult Execute<TBusiness, TResult>(Func<TBusiness, TResult> call) where TBusiness : class;
/// <summary>
/// Execute call to void service method
/// </summary>
/// <typeparam name="TBusiness">Service Interface</typeparam>
/// <param name="call">Service method</param>
void Execute<TBusiness>(Action<TBusiness> call) where TBusiness : class;
}
As you see, there are two methods in this interface. One of them will be used to call a service method which has a return type, the other one will be used for void methods in the service. You can put non-generic version of these methods to the interface too.
The implementation might be like this:
public class ServiceProxy : IProxy
{
protected void ExecuteCall<TContract>(Action<TContract> code) where TContract : class
{
var contractChannel = default(TContract);
try
{
//Create an instance of service client and call the method
contractChannel = Activator.CreateInstance<TContract>();
code(contractChannel);
((ICommunicationObject)contractChannel).Close();
}
catch (FaultException)
{
((ICommunicationObject)contractChannel).Abort();
}
catch (CommunicationException)
{
((ICommunicationObject)contractChannel).Abort();
}
catch (TimeoutException)
{
((ICommunicationObject)contractChannel).Abort();
}
}
public TResult Execute<TContract, TResult>(Func<TContract, TResult> call) where TContract : class
{
return ExecuteCall(call);
}
public void Execute<TContract>(Action<TContract> call) where TContract : class
{
ExecuteCall(call);
}
}
Then, you can use it like this:
var proxy = new ServiceProxy();
proxy.Execute<Service1Client>(a => a.MethodInTheService());
What's great about this approach and how you can make it perfect is:
You might not want to create the proxy as new ServiceProxy() but inject IProxy as ServiceProxy and use it as WCF client for now but if it changes to Web API in the future e.g., implement and inject WebApiProxy then.
You can use contract interfaces to call the proxy methods.
You can do whatever you want in the proxy class like caching the channels, getting the service endpoints from the database etc.
You don't need to dispose the client. In fact, if you dig deep into the code of ClientBase you'll see how it already implements IDisposable and when it gets disposed it just calls Close() - which has error handling paths to abort if something goes wrong.
Having said this, I would use a pattern similar to the below to close your client channel (you may need to cast to IChannel on Close and Abort):
try
{
client.Close();
}
catch
{
client.Abort();
}

Issue with import in MEF MVVM Silverlight 4

I am using MEF, MVVM and Silverlight4 and below is my code
Main.cs:
using System;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Diagnostics;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
public partial class Main : UserControl
{
public Main()
{
InitializeComponent();
// Satisfy the MEF imports for the class.
if (!DesignerProperties.IsInDesignTool)
{
CompositionInitializer.SatisfyImports(this);
}
}
/// <summary>
/// Sets the datacontext to the viewmodel for this view
/// </summary>
[Import(ViewModelTypes.MainViewModel)]
public object ViewModel
{
set
{
this.DataContext = value;
}
}
}
Viewmodel:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Windows.Input;
[Export(ViewModelTypes.MainViewModel)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MainViewModel : ViewModelBase
{
[ImportingConstructor]
public MainViewModel(IAuthenticationModel authModel, IprospectManagementModel managementModel)
{
this.authenticationModel = authModel;
this.managementModel = managementModel;
}
/// <summary>
/// The authentication model.
/// </summary>
private IAuthenticationModel authenticationModel;
/// <summary>
/// The Iprospect management model.
/// </summary>
private IprospectManagementModel managementModel;
}
Below is the error i am getting, Please do help me out trace the same.
The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No valid exports were found that match the constraint '(exportDefinition.ContractName == "MainViewModel")', invalid exports may have been rejected.
Resulting in:
Cannot set import 'IProspectCommonApp.Client.Main.ViewModel (ContractName="MainViewModel")' on part 'IProspectCommonApp.Client.Main'.
Element: IProspectCommonApp.Client.Main.ViewModel (ContractName="MainViewModel") --> IProspectCommonApp.Client.Main
It is probably failing because there is no IAuthenticationModel and/or IprospectManagementModel exported. The MainViewModel imports these via the ImportingConstructor, so it can't be created if they haven't been exported.
For more information on MEF debugging, see How to Debug and Diagnose MEF Failures.

NHibernate (3.1.0.4000) NullReferenceException using Query<> and NHibernate Facility

I have a problem with NHibernate, I can't seem to find any solution for.
In my project I have a simple entity (Batch), but whenever I try and run the following test, I get an exception.
I've triede a couple of different ways to perform a similar query, but almost identical exception for all (it differs in which LINQ method being executed).
The first test:
[Test]
public void QueryLatestBatch()
{
using (var session = SessionManager.OpenSession())
{
var batch = session.Query<Batch>()
.FirstOrDefault();
Assert.That(batch, Is.Not.Null);
}
}
The exception:
System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at System.Linq.Queryable.FirstOrDefault(IQueryable`1 source)
The second test:
[Test]
public void QueryLatestBatch2()
{
using (var session = SessionManager.OpenSession())
{
var batch = session.Query<Batch>()
.OrderBy(x => x.Executed)
.Take(1)
.SingleOrDefault();
Assert.That(batch, Is.Not.Null);
}
}
The exception:
System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at System.Linq.Queryable.SingleOrDefault(IQueryable`1 source)
However, this one is passing (using QueryOver<>):
[Test]
public void QueryOverLatestBatch()
{
using (var session = SessionManager.OpenSession())
{
var batch = session.QueryOver<Batch>()
.OrderBy(x => x.Executed).Asc
.Take(1)
.SingleOrDefault();
Assert.That(batch, Is.Not.Null);
Assert.That(batch.Executed, Is.LessThan(DateTime.Now));
}
}
Using the QueryOver<> API is not bad at all, but I'm just kind of baffled that the Query<> API isn't working, which is kind of sad, since the First() operation is very concise, and our developers really enjoy LINQ.
I really hope there is a solution to this, as it seems strange if these methods are failing such a simple test.
EDIT
I'm using Oracle 11g, my mappings are done with FluentNHibernate registered through Castle Windsor with the NHibernate Facility.
As I wrote, the odd thing is that the query works perfectly with the QueryOver<> API, but not through LINQ.
There is an issue with the current implementation of the LINQ extensionmethods for NHibernate 3.1.0.4000 used together with NHibernate Facility 2.0RC (and previous versions) (see: https://nhibernate.jira.com/browse/NH-2626 and discussion here: http://groups.google.com/group/castle-project-devel/browse_thread/thread/ac90148a8d4c8477)
The fix I am using at the moment is to simply ignore the LINQ extensionmethods provided by NHibernate and create it myself. They're really just one-liners:
public static class NHibernateLinqExtensions
{
/// <summary>
/// Performs a LINQ query on the specified type.
/// </summary>
/// <typeparam name="T">The type to perform the query on.</typeparam>
/// <param name="session"></param>
/// <returns>A new <see cref="IQueryable{T}"/>.</returns>
/// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks>
public static IQueryable<T> Linq<T>(this ISession session)
{
return new NhQueryable<T>(session.GetSessionImplementation());
}
/// <summary>
/// Performs a LINQ query on the specified type.
/// </summary>
/// <typeparam name="T">The type to perform the query on.</typeparam>
/// <param name="session"></param>
/// <returns>A new <see cref="IQueryable{T}"/>.</returns>
/// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks>
public static IQueryable<T> Linq<T>(this IStatelessSession session)
{
return new NhQueryable<T>(session.GetSessionImplementation());
}
}
Then, when I need to do a LINQ query, I just use session.Linq<EntityType>() instead of session.Query<EntityType>.
Hope it helps someone in the same situation that I was.
I found the following: http://groups.google.com/group/castle-project-users/browse_thread/thread/5efc9f3b7b5d6a08
Apparently there is an issue with the current version of the NHibernate Facility and NHibernate 3.1.0.4000.
I guess I'll just have to wait for a fix :)

Can I customize collation of query results in nHibernate?

In plain old SQL, I can do something like this:
select * from mytable COLLATE Latin1_General_CS_AS
Is there a way to specify the type of collation I want to use for a given query in nHibernate, in HQL or in criteria?
Germán Schuager has managed to specify collation at run time. Take a look here.
var user = session.CreateCriteria(typeof (User))
.Add(Expression.Sql("Username like ? collate Modern_Spanish_CS_AS", username, NHibernateUtil.String))
.UniqueResult<User>();
From the same link than rebelliard answer provide, Shuager also supplies a way to define a custom function for doing something similar. This has the advantage of being usable in HQL too.
His custom function implementation was too specific for your question and my own needs, so here is the implementation I have ended with:
/// <summary>
/// Customized dialect for allowing changing collation on <c>like</c> statements.
/// </summary>
public class CustomMsSqlDialect : MsSql2008Dialect
{
/// <summary>
/// Default constructor.
/// </summary>
public CustomMsSqlDialect()
{
RegisterFunction("withcollation",
new WithCollationFunction());
}
}
/// <summary>
/// Add collation to string argument.
/// </summary>
[Serializable]
public class WithCollationFunction : SQLFunctionTemplate, IFunctionGrammar
{
/// <summary>
/// Default constructor.
/// </summary>
public WithCollationFunction()
: base(NHibernateUtil.String, "?1 collate ?2")
{
}
bool IFunctionGrammar.IsSeparator(string token)
{
return false;
}
bool IFunctionGrammar.IsKnownArgument(string token)
{
return Regex.IsMatch(token, "[A-Z][A-Z0-9_]+_(?:CS|CI)_(?:AS|AI)(?:_KS)?(?:_WS)?", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
}
Mind the dialect base class, I have used 2008 dialect, you may wish to change that.
Do not forget to change your HQL dialect to your new custom dialect (using "dialect" configuration property of your session-factory for instance).
Example usage in HQL, standard query without collation customization :
from Cat as c
where c.Name like 'fel%'
With custom collation
from Cat as c
where c.Name like withCollation('fel%', French_CI_AI)
Works with Nhib 3.2.

How to get full intellisense tooltip comments working?

I've got some C++/CLI software which is all nice and documented in a C#'ish kind of way which means DOxygen is able to pull it out into some nice html. Is there any way I can get that same information to appear in the intellisense tool tips the way that the .net framework does?
For example, lets say this is my header file (MyApp.h):
/*************** MyApp.h ***************/
/// My namespace containing all my funky classes
namespace MyNamespace
{
using namespace System;
ref class WorldHunger;
/// A truly elegent class which solves all the worlds problems
public ref class MyClass
{
public:
/// Constructs a MyClass
MyClass()
{
}
/// <summary>Attempts to fix world hunger</summary>
/// <param name="problem">The problem to try and fix</param>
/// <returns>Whether or not the problem was solved</param>
bool FixWorldHunger( WorldHunger^ problem );
};
}
...and this it's corresponding implementation:
/*************** MyApp.cpp ***************/
#include "MyApp.h"
using namespace MyNamespace;
MyClass::MyClass()
{
}
bool MyClass::FixWorldHunger( WorldHunger^ problem )
{
bool result = false;
/// TODO: implement something clever
return result;
}
Here's what intellisense does for built in functions when I'm typing:
http://www.geekops.co.uk/photos/0000-00-02%20%28Forum%20images%29/BrokenIntellisense1.jpg
Here's what intellisense does for my own functions when I type:
http://www.geekops.co.uk/photos/0000-00-02%20%28Forum%20images%29/BrokenIntellisense2.jpg
Surely there's a way to do this?
Just to summarise, for this to work you need your comments in a compatible form:
/// <summary>
/// Retrieves the widget at the specified index
/// </summary>
/// <param name="widgetIndex">Index of the widget to retrieve.</param>
/// <returns>The widget at the specified index</returns>
Widget* GetWidget(int widgetIndex);
Then you simply right-click on the project in Visual Studio and go to properties > configuration properties > C/C++ > Output Files and change Generate XML Documentation Files to Yes.
When you rebuild your project ad import it somewhere else, you should see fully documented tooltips appear.