ASP.NET 2.0, SQL Server Express 2008, Sync Framework 1.0 C# Simplest Scenario Example - asp.net-2.0

Good Day Everyone,
I know, the versions I am talking about are rather obsolete by now but that's the tools I am stuck to work with at the workplace. This is my first question on StackOverflow, and I hope I will get the formatting right hehe ;-) Please pardon me for the long text, I am used to give a lot of details and, in a sense, I feel the more details I provide the more accurate might be the answers ;-)
In almost 10 years working in IT, I've always been able to find answers to my questions (i.e. solutions to my problems) by Googling well chosen keywords and expressions. Well, it looks like the aforementioned Sync Framework is either not very well known to the Internet community, or it is a real pain to try to understand its simplest concepts for most mortals. After extensive research I have to found a single, simple example of syncing SQL Express using Sync Framework 1.0 and the C# language, not even on MSDN! I am fairly new to ASP.NET / C# but I understand the concepts and I have a working web application that successfully stores and retrieve data from an SQL Server 2008 database. It has been in use by clients for two years now. We now have a requirement for the clients to be able to bring their data offline and be able to update it offline and then sync with the server. UPDATEs, INSERTs and DELETEs will occur at both ends.
What I am trying to find is VERY simple (or so I thought): C# code examples that uses SQL Server Change Tracking information (NOT custom Change Tracking) to sync the server (SQL Server 2008) and client computers (SQL Server 2008 Express, NOT Compact Edition). The simplest case would be a single table with few columns. I am fairly confident to understand the SQL Server part and I've prepared both sides of the database to receive sync requests from the client web application (enabled Change Tracking, PrimaryKeyID has data type GUID, the application's user account on the server has VIEW_CHANGE_TRACKING permission, etc. etc.)
I know it's the web application that serves as the interface between the two and that manage the sync session (in C#). I was quite naive to think that the only thing left to do was to provide the two connection strings, tell what tables are to sync and specify a bidirectional sync. Apparently, that's more complicated than that hehe. In a desperate attempt, I have tried to base my code on the following from Microsoft and adapt it to SQL Express (the example is for Compact). I am close to admit defeat and shamefully lower my head :-(
http://msdn.microsoft.com/en-us/library/bb726015%28v=sql.100%29.aspx
Based on the above (second section "Complete Example Using SQL Server Change Tracking"), I removed everything I do not need: things related to the password, the statistics, and the code applying changes to the data. I've also removed MS' numerous comment lines for clarity. I've manually applied changes at the SQL Server itself at both ends executing scripts in SSMS (and therefore there must be Change Tracking info that was generated and that is usable when the web app will request the sync). QUESTION 1: Am I wrong in saying so? Finally, I changed some stuff in an attempt to use objects relevant to SQL Express instead of Compact.
QUESTION 2: The code at Microsoft is apparently able to tell whether it is the initial (first) or subsequent sync of this replica. I don't have a clue how it can!
In the end, the code left in its simplest form is as below (with QUESTIONS 3, 4, 5 ;-), but shows some errors. I thank you VERY MUCH in advance for your help. Any comments and/or suggestions are welcome. I am sure if/when this is resolved it will benefit quite a lot of people out there. I will continue to research on it on my end (the boss won't give me a choice ;-) and I promise I will post the solution here if I ever succeed in syncing!
Thanks and have a great day everyone!
Kindest Regards,
Zyxy
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
//using System.Data.SqlServerCe;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.Server;
//using Microsoft.Synchronization.Data.SqlServerCe;
namespace some_namespace
{
public class SyncProgram
{
public SyncProgram()
{
// empty constructor
}
public static bool MainSync() // Entry point, say, called by a Sync button on an ASPX page.
{
bool boolSyncRes = false; // tells whether sync was a success or not
// Initial sync: they create a new instance of the Orchestrator.
ZyxySyncOrchestrator zyxySyncOrchestrator = new ZyxySyncOrchestrator();
// Subsequent synchronization.
// They don't. there was only irrelevant stats stuff here.
boolSyncRes = true;
return boolSyncRes;
}
}
public class ZyxySyncOrchestrator : SyncOrchestrator
{
public ZyxySyncOrchestrator()
{
Utility util = new Utility();
this.LocalProvider = new ZyxyServerSyncProvider(); // QUESTION 3: ??? cannot implicitly convert type DbServerSyncProvider to Microsoft.Synchronization.SyncProvider
//Instantiate a server synchronization provider and specify it
//as the remote provider for this synchronization agent.
this.RemoteProvider = new ZyxyServerSyncProvider(); // cannot implicitly convert type DbServerSyncProvider to Microsoft.Synchronization.SyncProvider
// QUESTION 4: Is the following code actually creating the base (user) table ZyxySync
// (as opposed to its change tracking metadata table)??
// I wasn't sure whether this part of the code on Microsoft's webpage was part of
// populating the db with sample data and structure or if it's really meant to deal with
// the change tracking metadata.
SyncTable zyxySyncTable = new SyncTable("ZyxySync");
zyxySyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
zyxySyncTable.SyncDirection = SyncDirection.DownloadOnly;
this.Configuration.SyncTables.Add(zyxySyncTable);
}
}
//Create a class that is derived from Microsoft.Synchronization.Server.DbServerSyncProvider.
public class ZyxyServerSyncProvider : DbServerSyncProvider
{
public ZyxyServerSyncProvider()
{
Utility util = new Utility();
SqlConnection serverConn = new SqlConnection(util.ServerConnString);
this.Connection = serverConn;
//Retrieve a new anchor value from the server. We use a timestamp value
//that is retrieved and stored in the client database.
//During each sync the new and last anchor values are used to determine the set of changes
SqlCommand selectNewAnchorCommand = new SqlCommand();
string newAnchorVariable = "#" + SyncSession.SyncNewReceivedAnchor;
selectNewAnchorCommand.CommandText =
"SELECT " + newAnchorVariable + " = change_tracking_current_version()";
selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.BigInt);
selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
selectNewAnchorCommand.Connection = serverConn;
this.SelectNewAnchorCommand = selectNewAnchorCommand;
//Create a SyncAdapter for the ZyxySync table by using
//the SqlSyncAdapterBuilder.
// Specify a name for the SyncAdapter that matches the
// the name specified for the corresponding SyncTable.
SqlSyncAdapterBuilder zyxyBuilder = new SqlSyncAdapterBuilder(serverConn);
zyxyBuilder.TableName = "dbo.ZyxySync";
zyxyBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking;
SyncAdapter zyxySyncAdapter = zyxyBuilder.ToSyncAdapter();
zyxySyncAdapter.TableName = "ZyxySync";
this.SyncAdapters.Add(zyxySyncAdapter);
}
}
// Class derived from Microsoft.Synchronization.Data.Server.DbServerSyncProvider
// QUESTION 5: Or should have I used the two below? I believe they only apply to SQL Compact...
//Microsoft.Synchronization.Data.ClientSyncProvider
//Microsoft.Synchronization.Data.ServerSyncProvider
//http://msdn.microsoft.com/en-us/library/microsoft.synchronization.data.clientsyncprovider%28v=sql.100%29.aspx
//http://msdn.microsoft.com/en-us/library/microsoft.synchronization.data.server.dbserversyncprovider%28d=printer,v=sql.100%29.aspx
public class ZyxyClientSyncProvider : DbServerSyncProvider
{
public ZyxyClientSyncProvider()
{
Utility util = new Utility();
SqlConnection clientConn = new SqlConnection(util.ClientConnString);
this.Connection = clientConn;
}
}
public class Utility
{
public string ClientConnString
{
get { return #"Data Source=localhost\LocalExpressInstance;Initial Catalog=DatabaseName;User ID=UserName;Password=WontTellYou;"; }
}
public string ServerConnString
{
get { return #" Data Source=ServerName\ServerInstance;Initial Catalog=DatabaseName;User ID=UserName;Password=WontTellYou;"; }
}
}
}

the SyncOrchestrator will not work with the DBServerSyncProvider.
In Sync Framework, there are two types of database providers: the offline provider and the peer-to-peer/collaboration providers. (they both work in offline scenario so thats confusing).
the offline provider is used in hub-spoke topologies. Only the client tracks what was synched. The server doesnt even know its part of a sync. this is the same provider used by the Local Database Cache Project item in Visual Studio. The only supported databases out of the box is SqlCeClientSyncProvider and DBServerSyncProvider and uses the SyncAgent to synchronize.
the peer-to-peer provider can be used in a peer-to-peer sync as well as hub-spoke scenarios. Each peer maintains metadata on what was synched. This uses the much newer SyncOrchestrator/SqlCeSyncProvider/SqlSyncProvider(works with SQL Server, Express, LocalDB, and SQL Azure). This uses a custom change tracking.
you can't interchange the providers used by SyncAgent and SyncOrchestrator. You can'r reuse the SQL commands either because they differ in the way they track, select, apply changes and record what was synched.

Ok I managed to make it work so here is a SIMPLE code sample that works (in my case anyway). In addition to the above steps (enabling Change Tracking, setting the right user permissions, etc.), what I did not understand is the following:
1) I found out that I can set it up so that the Sync Framework and sync session is all managed on the client side. Without any dependency on what's installed on the server, I was able to use SF 2.1 instead of the old 1.0. That helped a lot.
2) In preparation for the sync session, one must first PROVISION the database so that it is ready for sync. What I did is to run the following C# with the client connection string (so that it provisions the client db) and then run it again with the server connection string (so that it provisions the server db). This is a run once program (on both sides) to prepare the db. You do NOT run it for every sync session you establish.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Security.Principal;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.Server;
using Microsoft.Synchronization.Data.SqlServer; // SF 2.1
using Microsoft.Synchronization.SimpleProviders; // SF 2.1
using Microsoft.Synchronization.MetadataStorage; // SF 2.1
// ZYXY: Based on:
// http://msdn.microsoft.com/en-us/library/ff928603.aspx
// NOTES:
// - Microsoft Sync Framework 2.1 redistributable package must be installed on Client computers but is not required on the Server, as long as a server-side synchronization setup is performed by a client computer.
// This is a run once program.
namespace DISS_Database_Sync_Provisioning_Console
{
class Program
{
static void Main(string[] args)
{
SqlConnection sqlConn = new SqlConnection("Data Source=ServerName\\InstanceName;Initial Catalog=SomeDatabase;User ID=SOmeUser;Password=SomePassword;");
Console.Write("Provisioning database...");
// define a new scope named DISS_Sync_Scope
DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription("DISS_Sync_Scope");
// get the description of the ZyxySync table
DbSyncTableDescription tableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("dbo.ZyxySync", sqlConn);
// add the table description to the sync scope definition
scopeDesc.Tables.Add(tableDesc);
// create a server scope provisioning object based on the DISS_Sync_Scope
SqlSyncScopeProvisioning sqlProvision = new SqlSyncScopeProvisioning(sqlConn, scopeDesc);
// skipping the creation of base table since table already exists
sqlProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
// start the provisioning process
sqlProvision.Apply();
sqlConn.Close();
sqlConn.Dispose();
Console.Write("\nDatabase has been successfully configured for synchronization. Please press any key to exit.");
Console.Read();
}
}
}
3) Below is the code that is run everytime the synchronization is launched (e.g. when the user click their "Synchronize" button in their web application.)
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Principal;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.Server;
using Microsoft.Synchronization.Data.SqlServer; // SF 2.1
using Microsoft.Synchronization.SimpleProviders; // SF 2.1
using Microsoft.Synchronization.MetadataStorage; // SF 2.1
namespace diss_ssmb
{
public class SyncProgram
{
public SyncProgram()
{
// empty constructor
}
public static bool MainSync() // Entry point, say, called by a Sync button on an ASPX page.
{
bool boolSyncRes = false; // tells whether sync was a success or not
// Initial sync: they create a new instance of the Orchestrator.
ZyxySyncOrchestrator zyxySyncOrchestrator = new ZyxySyncOrchestrator();
// Subsequent synchronization.
// They don't. there was only irrelevant stats stuff here.
boolSyncRes = true;
return boolSyncRes;
}
}
public class ZyxySyncOrchestrator : SyncOrchestrator
{
public ZyxySyncOrchestrator()
{
Utility util = new Utility();
this.LocalProvider = new ZyxyClientSyncProvider();
//Instantiate a server synchronization provider and specify it
//as the remote provider for this synchronization agent.
this.RemoteProvider = new ZyxyServerSyncProvider();
SyncTable zyxySyncTable = new SyncTable("ZyxySync");
zyxySyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
zyxySyncTable.SyncDirection = SyncDirection.Bidirectional;
// this.Configuration.SyncTables.Add(zyxySyncTable);
this.Synchronize();
}
}
public class ZyxyServerSyncProvider : SqlSyncProvider
{
public ZyxyServerSyncProvider()
{
Utility util = new Utility();
SqlConnection serverConn = new SqlConnection(util.ServerConnString);
this.Connection = serverConn;
this.ScopeName = "DISS_Sync_Scope";
//Retrieve a new anchor value from the server. We use a timestamp value
//that is retrieved and stored in the client database.
//During each sync the new and last anchor values are used to determine the set of changes
SqlCommand selectNewAnchorCommand = new SqlCommand();
string newAnchorVariable = "#" + SyncSession.SyncNewReceivedAnchor;
selectNewAnchorCommand.CommandText =
"SELECT " + newAnchorVariable + " = change_tracking_current_version()";
selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.BigInt);
selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
selectNewAnchorCommand.Connection = serverConn;
// this.SelectNewAnchorCommand = selectNewAnchorCommand; // SF 2.1 commented out because SelectNewAnchorCommand isn't there.
SqlSyncAdapterBuilder zyxyBuilder = new SqlSyncAdapterBuilder(serverConn);
zyxyBuilder.TableName = "dbo.ZyxySync";
zyxyBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking;
SyncAdapter zyxySyncAdapter = zyxyBuilder.ToSyncAdapter();
zyxySyncAdapter.TableName = "ZyxySync";
// this.SyncAdapters.Add(zyxySyncAdapter); // SF 2.1 commented out because SelectNewAnchorCommand isn't there.
}
}
public class ZyxyClientSyncProvider : SqlSyncProvider
{
public ZyxyClientSyncProvider()
{
Utility util = new Utility();
SqlConnection clientConn = new SqlConnection(util.ClientConnString);
this.Connection = clientConn;
this.ScopeName = "DISS_Sync_Scope";
}
}
public class Utility
{
public string ClientConnString
{
get { return #"Some connection string such as in the above code sample"; }
}
public string ServerConnString
{
get { return #"Some serverconnection string such as in the above code sample"; }
}
}
}
4) The above successfully synched bidirectionally when INSERTs, UPDATEs and DELETEs occurred simultaneously at both ends between two consecutive sync session, HOWEVER, when no conflict had to be resolved (e.g. when the same record is updated at both ends). I yet have to do further testing in cases when there are conflicts that have to be resolved. How is the Sync Framework resolving such conflicts by default? I assume we can adjust these settings to tell it to establish the winner based either on...
- a timestamp value
- the replicaID
- the user role
- the transaction type
- ...
Anyways I truly hope that helps somebody, because I had a real hard time to figure it out from the web! Good luck!
Zyxy

Related

Is it possible to referencing the specific Xamarin.IOS into Xamarin Form

We are trying to combine the Xamarin code that one is created using Xamarin Form (non XAML) and the other one is purely Xamarin.IOS.
We look at the library of Xamarin.Essential and it looks it doesn't have CoreMotion.CMPedometer (iOS) as we need to count the steps.
Is it possible to run the code within the Xamarin Form (shared) to handle specific OS?
Thanks
Yes, you need to use a Dependency Service.
All of the doco can be found here ... https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction
An example is shown here in relation to device information (which has been cut down for simplicity reasons)
Firstly, you create an interface in your .NET standard/PCL project (if you're not using shared that is, which is likely the case).
using System;
namespace MyApplication.Interfaces
{
public interface IDeviceInfo
{
String GetDeviceModel();
String GetDeviceVersion();
}
}
Then down in your platform specific project, create a Dependency Service that implements that interface and directs the compiler to recognise the class as a Dependency Service.
using System;
using MyApplication.Interfaces;
using UIKit;
[assembly: Xamarin.Forms.Dependency(typeof(MyApplication.iOS.DeviceInfo))]
Namespace MyApplication.iOS
{
public class DeviceInfo : IDeviceInfo
{
UIDevice _device;
Public DeviceInfo()
{
_device = new UIDevice();
}
public string GetDeviceModel()
{
return _device.Model;
}
public string GetDeviceVersion()
{
return _device.SystemVersion;
}
}
}
Now from your .NET standard/PCL project, you can call the dependency service as required.
var deviceModel = DependencyService.Get<IDeviceInfo>().GetDeviceModel();
The above is specific for iOS which means you'd then need to implement the same concept for Android and UWP (or whatever is applicable).
See if that helps you.

Re-factor my DAL code to a Domain Driven Design or more modern design (C# 3.5)?

The development is limited to Visual Studio 2010 (Client approved software). We need to access the data through stored procedures. I want to avoid making it too complex with an aggressive schedule. Most of the design I see involve EF and LINQ, Not sure how to design for procs?
I want to create a separate code library project (used Web UI):
Application.Domain
- Interact get/put stored procedures, entities
Application.Web
- containing Web UI (JQuery, AJAX), WCF Service
Can anyone give me sample code on how to approach the Application.Domain?
Examples, I have read:
http://www.developer.com/net/dependency-injection-best-practices-in-an-n-tier-modular-application.html
http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/
DAL\AppDAL.cs:
public static IEnumerable<TasCriteria> GetTasCriterias()
{
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = "IVOOARINVENTORY_GET_TASCRITERIA";
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
var types = (from c in dataset.Tables[0].AsEnumerable()
select new TasCriteria()
{
TasCriteriaId = Convert.ToInt32(c["TasCriteriaId"]),
TasCriteriaDesc= c["CriteriaDesc"].ToString()
}).ToList<TasCriteria>();
return types;
}
}
Models\TasCriteria.cs:
public class TasCriteria
{
public int TasCriteriaId { get; set; }
public string TasCriteriaDesc { get; set; }
}
Service\Service.svc:
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest, Method = "GET")]
public List<TasCriteria> GetTasCriteriaLookup()
{
var tc = InventoryDAL.GetTasCriterias();
return tc.ToList();
}
If you:
are running on a tight schedule
have most of the business logic already on the DB side via sprocs/views
have not worked with EF before
I suggest you take a look at the Microsoft Enterprise Library, especially the Data Application Block. It will simplifie ALL of your DAL functionality (without using any ORM framework) and it follows the dependency inversion principle with the help of Unity which is a dependency injection container from Microsoft.
Some helpfull Data Application Block concepts:
Output Mapper
An output mapper takes the result set returned from a database (in the
form of rows and columns) and converts the data into a sequence of
objects.
// Create and execute a sproc accessor that uses default parameter and output mappings
var results = db.ExecuteSprocAccessor<Customer>("CustomerList", 2009, "WA");
Read the whole Retrieving Data as Objects topic.
Parameter Mapper
A parameter mapper takes the set of objects you want to pass to a
query and converts each one into a DbParameter object.
// Use a custom parameter mapper and the default output mappings
IParameterMapper paramMapper = new YourCustomParameterMapper();
var results = db.ExecuteSprocAccessor<Customer>("Customer List", paramMapper, yourCustomParamsArray);
For Entity generation I would try to use this tool. It builds a POCO class from a resultset returned by a sproc. I have not tried this tool yet and maybe there are better alternatives but it is something to get you start with, so you dont have to do this by hand.
If you are using .NET 3.5 then you have to work with Enterprise Library 5.0.
I hope this will steer you in the right direction.
first and foremost, make sure you abstract you DAL using dependency injection such as ninject or unity (or many others freely available). it is quite possible to have your DAL loosely coupled so that if you decide later on the EF (or any other ORM) is not the best course, changing it would no cost blood...
you do NOT want to have an AppDAL class with static methods to call the SP. at the very least add an interface and use injection, if only for the sake of unit testing.
whether you'll use EF or Nhibernate or any other ORM, that decision should be encapsulated in your DAL and not leak into other layers. the domain layer should use interfaces for repository classes from the DAL (and those contain references to the chosen ORM or data access classes).
these repositories will call the stored procedures and return your model classes (POCOs).
in one of my recent project we had this interface to provide basic CRUD operations:
public interface IRepository<T> where T : DomainEntity
{
T Get(Int64 id);
void SaveOrUpdate(T entity);
void Delete(T entity);
IQueryable<T> Find();
}
DomainEntity is a very simple class that all model clasess inherit.
In the rare cases where we needed to use stored procedures I'd create an additional interface that provides a GetXXXEntity method (1 or more), that would do the actual call to the SP.
so, when I need to get an entity from the DB using it's Id, it would look like:
_diWrapper.GetRepository<Person>().Get(id);
_diWrapper.GetRepository<Order>().Get(id);
_diWrapper is my wrapper for the dependency injection container (ninject in this case). I used a wrapper so I could easily replace ninject with something else if needed.
in common cases where I need to use linq:
_diWrapper.GetRepository<Person>().Find().Where(q => q.Name == "Jack").ToList();
the important thing was that I could replace Nhibernate with anything else rather quickly.
I strongly recommend you look at Fluent NHibernate, as it provides a simple solution that does not require much coding.
EDIT: here's an example of the repository class implementing the IRepository interface:
public class NhibernateRepository<T> : IRepository<T> where T : DomainEntity, new()
{
private ISession _session;
public NhibernateRepository()
{
_session = BaseNHibernateHelper<NHibernateHelper>.GetCurrentSession();
}
public T Get(Int64 id)
{
return _session.Get<T>(id);
}
public void SaveOrUpdate(T entity)
{
_session.SaveOrUpdate(entity);
}
public void Delete(T entity)
{
_session.Delete(entity);
}
public IQueryable<T> Find()
{
return _session.Query<T>();
}
}
note that in the constructor I use another nhibernate helper I created that wraps the session factory. this is where I have a dependency on nhibernate.
if I ever wanted to replace NH with another ORM, I would need to modify only the repository class (and the underlying supporting classes), you can see that NH does not leak outside the Repository class and no one that uses it are aware of the usage of NH.
I noticed that most people spoke of implementation/tech but no one mentioned the application or thrust of domain driven design . Well DDD is not necessarily something you can achieve by just adding in dapper/ef/enterprise library blocks. These can help, as can SOLID and things like cqs command/query separation but these are merely enablers there are more considerations and questions which need to be asked. Take a look at " domain driven design quickly" on infoq for a few more ideas.

upshot.js + signalr + knockout

Is it possible to combine upshot/knockout with signalr (I can only find questions about knockout and signalr only)?
For example if I add a Task using:
self.addTask = function () {
var task = new Task({
LastUpdated : new Date().toMSJSON(),
Title : this.newTaskText(),
IsDone : true
});
self.tasks.unshift(task);
}
in the view model, this will add it to the view automatically (based on the knockout data binding) and call:
public void InsertTask(Task task)
{
InsertEntity(task);
}
in the server. What if I also want to broadcast this to other clients.. is it possible using the same libraries? If it is.. what changes should I have to do / additional things I need to do? Are there any alternatives that will make this easier but still following the upcoming Microsoft ASP.NET MVC 4 stack?
You should be able to, On the server you can call
var connection = AspNetHost.DependencyResolver.Resolve<IConnectionManager().GetConnection<MyConnection>();
connection.Broadcast("Called from an mvc controller or server side method");
Or you could create a hub and implement it client side in the function:
self.addTask
to send a "addTask" message to clients.

Integration Testing Entity Framework code first with in-memory database

I'd like to run actual integration tests of my EF4.1 repositories against an in-memory database a la ayende's nhibernate version.
I have a code first model, against a legacy database (old table and column names need mapping to my entites using code configurations).
I'd like to be able to use Sqlite (or other) to:
Generate an in-memory database from my model
Create a DBContext for my model with this in-memory database
I have already in place IoC/DI of a IDBContextFactory which gets constructed with my (Generic) Repositories (also using a GenericRepository pattern)
There's bits and bobs on-line which suggest it should be possible, but not much for code-first approaches. Anyone know if this is possible?
Some snippets of my test library, see // THROWS ERROR marking runtime errors:
public class MyDbContextFactory : IDbContextFactory
{
private static object context;
public object CurrentContext
{
get {
if(context == null)
{
// ?? DOESN'T WORK AS THERE'S NO META DATA
var connBuilder = new EntityConnectionStringBuilder();
connBuilder.Provider = "System.Data.SQLite";
connBuilder.Metadata =
#"res://*/TestEfDb.csdl|res://*/TestEfDb.ssdl|res://*/TestEfDb.msl";
connBuilder.ProviderConnectionString =
ConfigurationManager.ConnectionStrings["DataContext"].Name;
var entConnection = new EntityConnection(connBuilder.ConnectionString);
// THROWS ERROR: sqlite Format of the initialization string does not
// conform to specification starting at index 0
// for connection string "Data Source=:memory:;Version=3;New=True;"
//var entConnection = new EntityConnection
// (ConfigurationManager.ConnectionStrings["DataContext"].Name);
context = new MyDbContext(entConnection);
}
return context;
}
}
}
...
[Test]
public void test_me()
{
var auditRespository = new AuditRepository(new MyDbContextFactory());
auditRespository.GetAll<Audit>();
}
Use SQL Compact 4.0 (download both SqlCE and tools by web platform installer) - EF Code first has direct support for that. The only difference will be that your application will use connection string to big SQL Server:
<add name="MyDbContext"
provider="System.Data.SqlClient"
connectionString=
"Data Source=...;InitialCatalog=...;Integrated Security=SSPI" />
and your tests will use connection string to SQL Compact:
<add name="MyDbContext"
provider="System.Data.SqlServerCe.4.0"
connectionString="Data Source=Database.sdf" />
Take a look at this article: Faking your LINQ provider. It describes how you can hide Entity Framework behind an abstraction, so that you can easily unit test your application, while still allowing to use LINQ (over IQueryable) queries against it in your application code.
Note that this does not completely remove the need of writing integration tests, since you would still need to test the database mapping layer and possibly test whether the chosen LINQ provider is able to execute the LINQ queries.

How to delete temporary files using Asp.net

In my application, I have some reports which needs to be viewed frequently.After viewing the reports many times by different users, it shows load error.For different systems, many temporary files are created.i need to delete those files in my single system.now i manually deleting all the temporary files in the temp directory and configure the IIS again.then the report loads properly.But we need to delete these temporary files frequently which makes our life dreadful.Only the report files needs to be deleted.How can i delete these temporary files automatically using code?
I have used the following code for this.but some files cant be deleted as those files are in use.Do those temporary files in other system can cause load error in our system?how can i solve this?
dim temp as string=Environment.GetEnvironmentVariable("TEMP")
dim k as sting()=System.IO.Directory.GetFiles(temp)
dim i as integer
For i=0 to k.length
On Error Resume Next
If k(i).Contains(".rpt") then
kill(k(i))
System.IO.File.Delete(k(i))
Next
Create a thread from the Application_Start() (or write a standalone exe)
You can just automate what you are manually doing.
You can delete these files with a older modifier day, once an hour, with a very simple program .
Assuming you are presenting these temporary files to the user can I suggest creating an HTTP handler. The handler will provide the ability to generate a file and deliver it to the user to be either downloaded or viewed in browser. This approach allows for the customization of caching.
The example below is only showing the handler portion, this is as basic as it gets as doesn't go into the file creation as I am not sure how you are creating the files currently. You can send a stream of some sort.
Example: (Sorry in C#, but you can go from here.)
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
namespace Handlers
{
/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
[WebService(Namespace = "http://www.tempuri.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ColorImage : IHttpHandler
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext context)
{
Bitmap bmGenerate = CreateBitmapMethod();
context.Response.ContentType = "image/png";
context.Response.AddHeader("Response-Type", "image/png");
using (MemoryStream memoryStream = new MemoryStream())
{
bmGenerate.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
memoryStream.WriteTo(context.Response.OutputStream);
}
}
}
}

Resources