Git In-Memory repository update target - libgit2

I'm still fairly new to the whole libgit2 and libgit2sharp codebases, but I've been trying to tackle the issue of In-Memory repositories and Refdb storage of references.
I've gotten everything almost working in my new branch:
Create the In-Memory repository and attach Refdb and Odb instance to it.
Create initial commit and set the reference for refs/heads/master.
Create the second commit...
The problem I run into now is updating refs/heads/master to the second commit. The UpdateTarget call to refs/heads/master runs into an error in git_reference_set_target:
LibGit2Sharp.NameConflictException : config value 'user.name' was not found
at LibGit2Sharp.Core.Ensure.HandleError(Int32 result) in \libgit2sharp\LibGit2Sharp\Core\Ensure.cs:line 154
at LibGit2Sharp.Core.Ensure.ZeroResult(Int32 result) in \libgit2sharp\LibGit2Sharp\Core\Ensure.cs:line 172
at LibGit2Sharp.Core.Proxy.git_reference_set_target(ReferenceHandle reference, ObjectId id, String logMessage) in \libgit2sharp\LibGit2Sharp\Core\Proxy.cs:line 2042
at LibGit2Sharp.ReferenceCollection.UpdateDirectReferenceTarget(Reference directRef, ObjectId targetId, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 476
at LibGit2Sharp.ReferenceCollection.UpdateTarget(Reference directRef, ObjectId targetId, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 470
at LibGit2Sharp.ReferenceCollection.UpdateTarget(Reference directRef, String objectish, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 498
at LibGit2Sharp.ReferenceCollection.UpdateTarget(String name, String canonicalRefNameOrObjectish, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 534
at LibGit2Sharp.ReferenceCollection.UpdateTarget(String name, String canonicalRefNameOrObjectish) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 565
at LibGit2Sharp.Tests.RepositoryFixture.CanCreateInMemoryRepositoryWithBackends() in \libgit2sharp\LibGit2Sharp.Tests\RepositoryFixture.cs:line 791
I have not been able to debug down into the libgit2 level, but from what I can tell the issue is in git_reference_create_matching call to git_reference__log_signature.
Is there a call I am missing that can update a reference in a Bare repo that doesn't require a signature? If any libgit2 guys know of how to do this in libgit2, I can implement it on the C# side.
As a test, I created two unit tests that perform the same actions In-Memory and on disk, and the In-Memory fails when calling UpdateTarget after creating the second commit. This follows the code on the wiki:
private Commit CreateCommit(Repository repository, string fileName, string content, string message = null)
{
if (message == null)
{
message = "i'm a commit message :)";
}
Blob newBlob = repository.ObjectDatabase.CreateBlobFromContent(content);
// Put the blob in a tree
TreeDefinition td = new TreeDefinition();
td.Add(fileName, newBlob, Mode.NonExecutableFile);
Tree tree = repository.ObjectDatabase.CreateTree(td);
// Committer and author
Signature committer = new Signature("Auser", "auser#example.com", DateTime.Now);
Signature author = committer;
// Create binary stream from the text
return repository.ObjectDatabase.CreateCommit(
author,
committer,
message,
tree,
repository.Commits,
true);
}
[Fact]
public void CanCreateRepositoryWithoutBackends()
{
SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
Repository.Init(scd.RootedDirectoryPath, true);
ObjectId commit1Id;
using (var repository = new Repository(scd.RootedDirectoryPath))
{
Commit commit1 = CreateCommit(repository, "filePath.txt", "Hello commit 1!");
commit1Id = commit1.Id;
repository.Refs.Add("refs/heads/master", commit1.Id);
Assert.Equal(1, repository.Commits.Count());
Assert.NotNull(repository.Refs.Head);
Assert.Equal(1, repository.Refs.Count());
}
using (var repository = new Repository(scd.RootedDirectoryPath))
{
Commit commit2 = CreateCommit(repository, "filePath.txt", "Hello commit 2!");
Assert.Equal(commit1Id, commit2.Parents.First().Id);
repository.Refs.UpdateTarget("refs/heads/master", commit2.Sha);
Assert.Equal(2, repository.Commits.Count());
Assert.Equal(1, repository.Refs.Count());
Assert.NotNull(repository.Refs.Head);
Assert.Equal(commit2.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
}
}
[Fact]
public void CanCreateInMemoryRepositoryWithBackends()
{
OdbBackendFixture.MockOdbBackend odbBackend = new OdbBackendFixture.MockOdbBackend();
RefdbBackendFixture.MockRefdbBackend refdbBackend = new RefdbBackendFixture.MockRefdbBackend();
ObjectId commit1Id;
using (var repository = new Repository())
{
repository.Refs.SetBackend(refdbBackend);
repository.ObjectDatabase.AddBackend(odbBackend, 5);
Commit commit1 = CreateCommit(repository, "filePath.txt", "Hello commit 1!");
commit1Id = commit1.Id;
repository.Refs.Add("refs/heads/master", commit1.Id);
Assert.Equal(1, repository.Commits.Count());
Assert.NotNull(repository.Refs.Head);
Assert.Equal(commit1.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
// Emulating Git, repository.Refs enumerable does not include the HEAD.
// Thus, repository.Refs.Count will be 1 and refdbBackend.References.Count will be 2.
Assert.Equal(1, repository.Refs.Count());
Assert.Equal(2, refdbBackend.References.Count);
}
using (var repository = new Repository())
{
repository.Refs.SetBackend(refdbBackend);
repository.ObjectDatabase.AddBackend(odbBackend, 5);
Commit commit2 = CreateCommit(repository, "filePath.txt", "Hello commit 2!");
Assert.Equal(commit1Id, commit2.Parents.First().Id);
//repository.Refs.UpdateTarget(repository.Refs["refs/heads/master"], commit2.Id);
//var master = repository.Refs["refs/heads/master"];
//Assert.Equal(commit1Id.Sha, master.TargetIdentifier);
repository.Refs.UpdateTarget("refs/heads/master", commit2.Sha); // fails at LibGit2Sharp.Core.Proxy.git_reference_set_target(ReferenceHandle reference, ObjectId id, String logMessage)
//repository.Refs.Add("refs/heads/master", commit2.Id); // fails at LibGit2Sharp.Core.Proxy.git_reference_create(RepositoryHandle repo, String name, ObjectId targetId, Boolean allowOverwrite, String logMessage)
Assert.Equal(2, repository.Commits.Count());
Assert.Equal(1, repository.Refs.Count());
Assert.NotNull(repository.Refs.Head);
Assert.Equal(commit2.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
}
}

Related

Using TFS API to rollback a changeset

I am trying to use the TFS API to rollback a changeset.
I tried using all Workspace.Rollback methods but the action does nothing (The GetStatus returned says NoActionNeeded:true).
Has anyone managed to get this to work and can send a working code sample?
From the documentation of the method:
public GetStatus Rollback(
string[] paths,
RecursionType recursion,
VersionSpec itemSpecVersion,
VersionSpec versionFrom,
VersionSpec versionTo,
LockLevel lockLevel,
RollbackOptions options,
string[] itemAttributeFilters
)
I do not understand what the parameter VersionSpec itemSpecVersion means.
It says 'The version spec that identifies the item to which the user is referring.' but then how does it differ from the parameter versionFrom?
What should I pass as the itemAttributeFilters (the last paramter)?
You can rollback changeset programmatically with the following code:
TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("tfsCollectionURL"));
VersionControlServer vcs = (VersionControlServer)tpc.GetService(typeof(VersionControlServer));
string workingDirectory = #"localPath";
string[] workigDnirectoryArr = new string[] { workingDirectory };
Workspace ws = vcs.GetWorkspace("$/serverPath");
int fromCS = 456; //changesetid
int toCS = 495; //changesetid
VersionSpec versionSpecFrom = new ChangesetVersionSpec(fromCS);
VersionSpec versionSpecTo = new ChangesetVersionSpec(toCS);
var status = ws.Rollback(workigDnirectoryArr, RecursionType.None,null, versionSpecFrom, versionSpecTo,LockLevel.None,RollbackOptions.None,null);

Error occurred creating story: "Cannot parse object reference from", Rally

I am trying to create user stories in rally by java. Am failing to get response and it throwing " Cannot parse object reference from ".
Brief on my rally : Let assume I have Project name "Characters" and its has subs as A, B, C, D. I have to create my user stories in C. Is my following code correct in this prospect? Can anyone please help?
package samplerally;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.CreateRequest;
import com.rallydev.rest.request.GetRequest;
import com.rallydev.rest.response.CreateResponse;
import com.rallydev.rest.util.Ref;
public class CreateStory {
public static void main(String[] args) throws URISyntaxException,IOException {
String host = "https://rally1.rallydev.com";
String username = "name#comp.com";
String password = "password";
String wsapiVersion = "v2.0";
String applicationName = "C";
RallyRestApi restApi = new RallyRestApi(new URI(host),username,password);
restApi.setWsapiVersion(wsapiVersion);
restApi.setApplicationName(applicationName);
try {
for (int i = 0; i < 3; i++) {
// Add a story
System.out.println("Creating a story...");
JsonObject newStory = new JsonObject();
newStory.addProperty("Name", "my story");
newStory.addProperty("Project", "Characters");
CreateRequest createRequest = new CreateRequest("hierarchicalrequirement", newStory);
CreateResponse createResponse = restApi.create(createRequest);
System.out.println("Response ::: "+createResponse.wasSuccessful());
if (createResponse.wasSuccessful()) {
System.out.println(String.format("Created %s",createResponse.getObject().get("_ref").getAsString()));
// Read story
String ref = Ref.getRelativeRef(createResponse.getObject().get("_ref").getAsString());
System.out.println(String.format("\nReading Story %s...",ref));
GetRequest getRequest = new GetRequest(ref);
} else {
String[] createErrors;
createErrors = createResponse.getErrors();
System.out.println("Error occurred creating story: ");
for (int j = 0; j < createErrors.length; j++) {
System.out.println(createErrors[j]);
}
}
}
} finally {
// Release all resources
restApi.close();
}
}
}
And I am getting error as :
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
Picked up _JAVA_OPTIONS: -Xrunjvmhook -Xbootclasspath/a:"C:\Program Files\HP\Unified Functional Testing\bin\java_shared\classes";"C:\Program Files\HP\Unified Functional Testing\bin\java_shared\classes\jasmine.jar"
Please help. New to rally. Thanks in advance
When setting reference fields such as Project, Iteration, Release, WorkProduduct, Parent, etc that point to full objects use the reference,and not the Name.
Find out the unique ObjectID of the Project "C", e.g. 123456.
Replace:
newStory.addProperty("Project", "Characters");
with
newStory.addProperty("Project", "/project/123456");
To find ObjectID of a project you may either query by its name in WS API, or look at the URL of one of Rally pages in the address bar, while in that project, e.g. URL of a Backlog page: https://rally1.rallydev.com/#/123456/backlog
If there is a d or u appended to ObjectID string, e.g. 123456d, do not include it in string. In the URL it indicates if you are currently scoping up or down.

Libgit2sharp Push Performance Degrading With Many Commits

The project I am working on uses GIT in a weird way. Essentially it writes and pushes one commit at a time. The project could result in one branch having hundreds of thousands of commits. When testing we found that after only about 500 commits the performance of the GIT push started to degrade. Upon further investigation using a process monitor we believe that the degradation is due to a walk of the entire tree for the branch being pushed. Since we are only ever pushing one new commit at any given time is there any way to optimize this?
Alternatively is there a way to limit the commit history to be something like 50 commits to reduce this overhead?
I am using LibGit2Sharp Version 0.20.1.0
Update 1
To test I wrote the following code:
void Main()
{
string remotePath = #"E:\GIT Test\Remote";
string localPath = #"E:\GIT Test\Local";
string localFilePath = Path.Combine(localPath, "TestFile.txt");
Repository.Init(remotePath, true);
Repository.Clone(remotePath, localPath);
Repository repo = new Repository(localPath);
for(int i = 0; i < 2000; i++)
{
File.WriteAllText(localFilePath, RandomString((i % 2 + 1) * 10));
repo.Stage(localFilePath);
Commit commit = repo.Commit(
string.Format("Commit number: {0}", i),
new Signature("TestAuthor", "TestEmail#Test.com", System.DateTimeOffset.Now),
new Signature("TestAuthor", "TestEmail#Test.com", System.DateTimeOffset.Now));
Stopwatch pushWatch = Stopwatch.StartNew();
Remote defaultRemote = repo.Network.Remotes["origin"];
repo.Network.Push(defaultRemote, "refs/heads/master:refs/heads/master");
pushWatch.Stop();
Trace.WriteLine(string.Format("Push {0} took {1}ms", i, pushWatch.ElapsedMilliseconds));
}
}
private const string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static readonly Random Random = new Random();
/// <summary>
/// Get a Random string of the specified length
/// </summary>
public static string RandomString(int size)
{
char[] buffer = new char[size];
for (int i = 0; i < size; i++)
{
buffer[i] = Characters[Random.Next(Characters.Length)];
}
return new string(buffer);
}
And ran the process monitor found here:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
The time for each push ended up being generally low with large spikes in time increasing both in frequency and in latency. When looking at the output from the process monitor I believe these spikes lined up with a long stretch where objects in the .git\objects folder were being accessed. For some reason occasionally on a pull there are large reads of the objects which when looked at closer appears to be a walk through the commits and objects.
The above flow is a condensed version of the actual flow we were actually doing in the project. In our actual flow we would first create a new branch "Temp" from "Master", make a commit to "Temp", push "Temp", merge "Temp" with "Master" then push "Master". When we timed each part of that flow we found the push was by far the longest running operation and it was increasing in elapsed time as the commits piled up on "Master".
Update 2
I recently updated to use libgit2sharp version 0.20.1.0 and this problem still exists. Does anyone know why this occurs?
Update 3
We change some of our code to create the temporary branch off of the first commit ever on the "Master" branch to reduce the commit tree traversal overhead but found it still exists. Below is an example that should be easy to compile and run. It shows the tree traversal happens when you create a new branch regardless of the commit position. To see the tree traversal I used the process monitor tool above and command line GIT Bash to examine what each object it opened was. Does anyone know why this happens? Is it expected behavior or am I just doing something wrong? It appears to be the push that causes the issue.
void Main()
{
string remotePath = #"E:\GIT Test\Remote";
string localPath = #"E:\GIT Test\Local";
string localFilePath = Path.Combine(localPath, "TestFile.txt");
Repository.Init(remotePath, true);
Repository.Clone(remotePath, localPath);
// Setup Initial Commit
string newBranch;
using (Repository repo = new Repository(localPath))
{
CommitRandomFile(repo, 0, localFilePath, "master");
newBranch = CreateNewBranch(repo, "master");
repo.Checkout(newBranch);
}
// Commit 1000 times to the new branch
for(int i = 1; i < 1001; i++)
{
using(Repository repo = new Repository(localPath))
{
CommitRandomFile(repo, i, localFilePath, newBranch);
}
}
// Create a single new branch from the first commit ever
// For some reason seems to walk the entire commit tree
using(Repository repo = new Repository(localPath))
{
CreateNewBranch(repo, "master");
}
}
private const string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static readonly Random Random = new Random();
/// <summary>
/// Generate and commit a random file to the specified branch
/// </summary>
public static void CommitRandomFile(Repository repo, int seed, string rootPath, string branch)
{
File.WriteAllText(rootPath, RandomString((seed % 2 + 1) * 10));
repo.Stage(rootPath);
Commit commit = repo.Commit(
string.Format("Commit: {0}", seed),
new Signature("TestAuthor", "TestEmail#Test.com", System.DateTimeOffset.Now),
new Signature("TestAuthor", "TestEmail#Test.com", System.DateTimeOffset.Now));
Stopwatch pushWatch = Stopwatch.StartNew();
repo.Network.Push(repo.Network.Remotes["origin"], "refs/heads/" + branch + ":refs/heads/" + branch);
pushWatch.Stop();
Trace.WriteLine(string.Format("Push {0} took {1}ms", seed, pushWatch.ElapsedMilliseconds));
}
/// <summary>
/// Create a new branch from the specified source
/// </summary>
public static string CreateNewBranch(Repository repo, string sourceBranch)
{
Branch source = repo.Branches[sourceBranch];
string newBranch = Guid.NewGuid().ToString();
repo.Branches.Add(newBranch, source.Tip);
Stopwatch pushNewBranchWatch = Stopwatch.StartNew();
repo.Network.Push(repo.Network.Remotes["origin"], "refs/heads/" + newBranch + ":refs/heads/" + newBranch);
pushNewBranchWatch.Stop();
Trace.WriteLine(string.Format("Push of new branch {0} took {1}ms", newBranch, pushNewBranchWatch.ElapsedMilliseconds));
return newBranch;
}
/// <summary>
/// Get a Random string of the specified length
/// </summary>
public static string RandomString(int size)
{
char[] buffer = new char[size];
for (int i = 0; i < size; i++)
{
buffer[i] = Characters[Random.Next(Characters.Length)];
}
return new string(buffer);
}

edit any file which is wrapped in the jar file

I want to implement Following stuff with my java code in eclipse.
i need to edit the .dict file which is in directory of jar file.
my directory structure is like
C:\Users\bhavik.kama\Desktop\Sphinx\sphinx4-1.0beta6-bin\sphinx4-1.0beta6\modified_jar_dict\*WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar*\dict\**cmudict04.dict**
Text with bold character is my text file name which i want to edit
and text with italic foramt is my .jar file
now how can i edit this cmudict04.dict file which is reside in WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar\dict\ directory on runtime with java application.
and i want the jar file with the updated file i have edited.
please can u provide me any help?
thnank you in advance.
I would recommend to use java.util.zip.Using these classes you can read and write the files inside the archive .But modifying the contents is not guaranteed because it may be cached.
Sample tutorial
http://www.javaworld.com/community/node/8362
You can't edit files that are contained in a Jar file and have it saved in the Jar file ... Without, extracting the file first, updating it and creating a new Jar by copying the contents of the old one over to the new one, deleting the old one and renaming the new one in its place...
My suggestion is find a better solution
I had succeded to edit jar file and wrap it back as it is...with the following code
public void run() throws IOException
{
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
// JarOutputStream target = new JarOutputStream(new FileOutputStream("E:\\hiren1\\WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar"), manifest);
// add(new File("E:\\hiren1\\WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/"), target);
JarOutputStream target = new JarOutputStream(new FileOutputStream("C:\\Users\\bhavik.kama\\Desktop\\Sphinx\\sphinx4-1.0beta6-bin\\sphinx4-1.0beta6\\modified_jar_dict\\WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.jar"), manifest);
add(new File("C:\\Users\\bhavik.kama\\Desktop\\Sphinx\\sphinx4-1.0beta6-bin\\sphinx4-1.0beta6\\modified_jar_dict\\WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/"), target);
target.close();
}
private void add(File source, JarOutputStream target) throws IOException
{
BufferedInputStream in = null;
try
{
if (source.isDirectory())
{
//String name = source.getPath().replace("\\", "/");
if(isFirst)
{
firstDir = source.getParent() + "\\";
isFirst = false;
}
String name = source.getPath();
name = name.replace(firstDir,"");
if (!name.isEmpty())
{
if (!name.endsWith("/"))
name += "/";
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File nestedFile: source.listFiles())
add(nestedFile, target);
return;
}
String name = source.getPath();
name = name.replace(firstDir,"").replace("\\", "/");
//JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
JarEntry entry = new JarEntry(name);
//JarEntry entry = new JarEntry(source.getName());
entry.setTime(source.lastModified());
target.putNextEntry(entry);
in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true)
{
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
}
finally
{
if (in != null)
in.close();
}
}

SharpArch.Data.NHibernate.Repository.SaveOrUpdate() don't save

I have this code for filling DB, but after finish, DB is still empty. Only number in hibernate_unique_key table is higher.
The next thing which is interesting is, that during debugging instances has id, after save, but not like 1,2,3... but very high like 60083, 60084, ... etc. (It not seems normal, because there is only several rows for save).
Before that, there was some problems with references and so on, but now there is no error message or exception.
code is there:
using System;
using NHibernate.Cfg;
using SharpArch.Data.NHibernate;
using LaboratorniMetody.Data.NHibernateMaps;
using SharpArch.Core.PersistenceSupport;
using LaboratorniMetody.Core;
namespace LaboratorniMetody.FillSchema
{
class Program
{
private static Configuration configuration;
static void Main(string[] args)
{
configuration = NHibernateSession.Init(new SimpleSessionStorage(), new String[] { "LaboratorniMetody.Data" },
new AutoPersistenceModelGenerator().Generate(),
"../../../../app/LaboratorniMetody.Web/NHibernate.config");
IRepository<Laboratory> LaboratoryRepository = new Repository<Laboratory>();
Laboratory Laboratory1 = new Laboratory() { Name = "Hematologie" };//Method
Laboratory l = LaboratoryRepository.SaveOrUpdate(Laboratory1);
Laboratory Laboratory2 = new Laboratory() { Name = "Patologie" };//Method
LaboratoryRepository.SaveOrUpdate(Laboratory2);
Laboratory Laboratory3 = new Laboratory() { Name = "Laboratoře" };//Method
LaboratoryRepository.SaveOrUpdate(Laboratory3);
}
}
}
I use DB schema genereted by NUnit from Project.Core classes.
Do you have any ideas where i should find problem? I have 2 very similar project which working with no problem. I Copyed this code from one of them and there is practicly no differents (except DB model and so on.)
You need to do your changes in a transaction and commit the transaction afterwards.
using(var tx = NHibernateSession.Current.BeginTransaction())
{
IRepository<Laboratory> LaboratoryRepository = new Repository<Laboratory>();
Laboratory Laboratory1 = new Laboratory() { Name = "Hematologie" };//Method
Laboratory l = LaboratoryRepository.SaveOrUpdate(Laboratory1);
Laboratory Laboratory2 = new Laboratory() { Name = "Patologie" };//Method
LaboratoryRepository.SaveOrUpdate(Laboratory2);
Laboratory Laboratory3 = new Laboratory() { Name = "Laboratoře" };//Method
LaboratoryRepository.SaveOrUpdate(Laboratory3);
tx.Commit();
}
I advise to look at the SharpArchContrib project wiki, which has some samples on using SharpArch in a windows app/service and how to use Transaction attributes from there.
https://github.com/sharparchitecture/Sharp-Architecture-Contrib/wiki/