GithubHelp home page GithubHelp logo

riteshrao / ncommon Goto Github PK

View Code? Open in Web Editor NEW
219.0 28.0 61.0 57.55 MB

A framework for implementing commonly used design patterns when using Domain Driven Design

Home Page: www.codeinsanity.com

C# 89.63% ASP 0.50% JavaScript 1.93% PowerShell 7.93%

ncommon's Introduction

NCommon

NCommon is a light weight framework that provides implementations of commonly used design patterns for applications using a Domain Driven Design approach.

Building NCommon

Building NCommon is done via a [psake] (http://github.com/JamesKovacs/psake) script. Before running the psake build script, make sure you have Powershell 2.0 installed.

Import-Module .\psake.psm1
Invoke-psake .\default.ps1

NCommon binaries are built and placed in an out directory under the root folder.

For documentation on NCommon, visit http://riteshrao.github.com/ncommon

ncommon's People

Contributors

apavlychev avatar riteshrao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ncommon's Issues

Possible race condition in NHUnitOfWork

I'm seeing (or rare occasions), the following exception:

System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at NCommon.Data.NHibernate.NHUnitOfWork.GetSessionT

I believe this is being caused by this line in NHUnitOfWork.GetSession:

_openSessions.Add(sessionKey, session);

I'm guessing that this should probably be changed to:

_openSesions(sessionKey) = session;

Or perhaps another check is needed before the add?

multiple databases support

This is a very good library.
But without multiple databases support, it's impossible to use it in large projects.
For example, those projects that use one database for single signon and another for business data.

TransactionManager is not Thread Safe

The TransactionManager class is not Thread Safe. I've added locks to the following methods to solve the problem.

    public UnitOfWorkTransaction CurrentTransaction
    public void EnlistScope(IUnitOfWorkScope scope, TransactionMode mode)
    void OnTransactionDisposing(UnitOfWorkTransaction transaction)
    void Dispose(bool disposing)

Basically, anywhere the underlying _transactions object is changed needs to have a lock added.

Minor considerations

  1. Build fails if path has spaces (this may be related to psake)
  2. Ninject service locator adapter is missing (CommonServiceLocator.NinjectAdapter.dll – not sure if this is important but Windsor one was included)
  3. The “I” in Ninject is lowercase (this is a really an important one ;)
  4. The build process stops as soon as the first test fails (e.g. Linq2Sql)…Is there a way to just report failure and keep going (so you can see if anything else failed)
  5. Consider adding CLS-Compliant attribute in AssmblyInfo.cs files

Add Stateless session to NHibernate UOW impl

Would be great if you were able to access a stateless session via. the nhibernate unit of work impl - this is useful in bulk operations scenarios where you don't want to deal with the overhead of session dirty tracking, etc.

Ncommon.NHibernate is not strongly signed

Probably due to the lack of signing on the NHibernate.Linq asembly (the one available publically) - I have a version built using a strong named key, if you're interested.

Trouble boostrapping Session storage

Perhaps I'm going about this incorrectly, but if I attempt to configure the NCommon session storage from Application_Start, HttpContext.Current.Session is null, and this causes some big problems down the line when the default session storage is initialized. I'm guessing this may have to be initialized lazily?

Problem with saving attached Entity with Entity Framework

When you load entity, commit the unit of work, after the change attempt on such entity there is no way to attach(reattach) it to context and submit changes to database. I have problem when I was using IEntityWithKey but I suppose that similar problem can happens for POCO type of entities.

Problem could be resolved by adding:
public void Attach(T entity) where T : class
{
//If the entity implementes the IEntityWithKey interface then we should use Context's Attach metho
//instead of the set's Attach. Getting an exception
//"Mapping and metadata information could not be found for EntityType 'System.Data.Objects.DataClasses.IEntityWithKey"
//when using set's Attach.
var entityWithKey = typeof (IEntityWithKey);
if (entityWithKey.IsAssignableFrom(entity.GetType()))
{
_context.Attach((IEntityWithKey)entity);
// new line seem to solve the problem
_context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
return;
}

        GetObjectSet<T>().Attach(entity);
        //_context.DetectChanges(); //Required for POCO entities
    }

Using UnitOfwork and parallell tasks

Hi,
I have the following problem:
I have an application which does extensive work. Until now all this have been done synchronously. But then I identified task that may as well run in parallell. Therefore I wanted to use the .net 4.0 parallell/task library. But when setting up this, I first get a problem with the UnitOfWorkScope. Running tasks in their own thread seems to loose the current UnitOfWorkScope I run the complete task in.
So I then try to create a new scope within the working thread for the individual tasks, but then I received error "The underlying provider failed on EnlistTransaction".

I guess if I were able to get hold of the UnitOfWorkScope across threads, it would go well.

any solution/workaround to this?

Missing POCO support

Trying to create a repository using POCO template in Visul Studio. Not able to save when using EFRepository cause its attach casts the TEntity to an IEntityWithKey (which the poco class) do not support.

Poco support would be great:)

Composite unit of work?

I'm currently using Raven side-by-side with Nhibernate in a project. I'd ideally like to create a unit of work implementation for Raven itself (a trivial task). However, I'd love to have these two units of work use the same transaction, etc....have you considered some sort of composite unit of work implementation that would allow for several units of work to be used in conjunction?

Add an option for transaction timeout

Currently there appears to be no way to configure a timeout for the transactions managed by the unit of work. It would be extremely helpful to be able to configure a default transaction timeout in addition to being able to override this at runtime (say for a long-running process such as an import or report) - any thoughts on how this could be incorporated?

TransactionManager IDispose pattern.

Private field "_disposed" in "TransactionManager " class has never assigned value to.

Shouldn't it be set to true in "void Dispose(bool disposing)" function?

    void Dispose(bool disposing)
    {
        if ( !_disposed ) {
            if ( disposing ) {
                ...
            }
        }
        _disposed = true;
    }

Saving Objects Containing Attached Properties

I have a question regarding how to use NCommon (Entity Framework module) to save objects that have not been persisted before. However, the object I am trying to save has properties of complex types that have been added before. So, for example, let's say I have a Classroom object which has a one to many relationship with a Student object like so...

class Classroom
{
public virtual IEnumerable Students { get; set; }
}

If the Classroom's Student collection has a Student object that already exists in the database, I can't call Save() on the IRepository (EFRepository) because Save() simply calls SaveChanges on the ObjectContext. Thus, I get "duplicate key exceptions" because EntityFramework is trying to add a Student object that already exists. So, is it possible to have a Save() method that will smartly handle objects that have yet to be persisted which contain properties that have been persisted?

Identity key problems

I have problems with identiy keys, It will not update until I commit the scope, this is a problem because i need the identity to fill other entities.

Support Nhibernate 3.0

Now that 3.0 GA is here; ncommon should have a build targetting the latest Nhibernate version.

Still missing documentation

Hi,
I like the concept behind NCommon. But still I'm having problem finding any good documentation. The links at this page: http://riteshrao.github.com/ncommon/docs/, does not work. I want to use/try this framework but would very much be able to be able to support "my programming desicions" on a good, detailed and updated documentation. I also miss docs on the business and validation rule patterns/implementation.
So, can we expect to see updated documentation at the mentioned web site in the near future?

CompositeUserTypes CANNOT Short-circuit NullSafeSet

Because this implementation is cited as an example across the internet. I feel it's important to point out a data corrupting bug in this generic implementation.

NullSafeSet needs to get called on each composite property with null when value is null.

If you don't and you have a batch save of objects with said composite type, any null value property will get be updated in the DB with the last nonnull value saved

public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session)
{
if (value == null)
return;
var propIndex = index;
for (var i = 0; i < _properties.Count; i++)
{
var property = _properties[i];
var propValue = property.GetValue(value, null);
NHibernateUtil.GuessType(property.PropertyType).NullSafeSet(cmd, propValue, propIndex, session);
propIndex++;
}
}

UnitOfWorkManager is not Thread Safe

UnitOfWorkManager is not thread safe. Multiple TransactionManagers can be created in a multi-threaded environment.

To fix this issue, I've changed the following method to add a double-lock on the TransactionManager creation.

private static readonly object _lock = new Object();
static readonly Func DefaultTransactionManager = () =>
{
_logger.Debug(x => x("Using default UnitOfWorkManager provider to resolve current transaction manager."));
var state = ServiceLocator.Current.GetInstance();
var transactionManager = state.Local.Get(LocalTransactionManagerKey);
if (transactionManager == null)
{
lock (_lock)
{
if (transactionManager == null)
{
_logger.Debug(x => x("No valid ITransactionManager found in Local state. Creating a new TransactionManager."));
transactionManager = new TransactionManager();
state.Local.Put(LocalTransactionManagerKey, transactionManager);
}
}
}
return transactionManager;
};

Documentation and/or Examples

NCommon looks like an awesome library, but is prohibitively difficult to navigate for a beginner of the patterns it covers. Could we have some documentation, please? the github pages have a well structured index, and would be really useful if the content is filled in.

Thanks in advance!

PS: I did take a look at the tests and the author's blog.

Changes from earlier version

Hi. I would like to upgrade to the latest version of NCommon. However, I noticed some changes and I would like to ask if you can help by pointing me out to articles / forums where this has been addressed.

  1. What happened to the Store container class?
  2. What happened to the NHRepository constructor that accepts ISession?

If they're both gone, can you suggest what I should do in place of these?

Thanks very much.

Query to Return Distinct Root Entity

Think it would be good include a property like "WithDistinctRootEntity" to IRepository.

This would allow us to take advantage of the nhibernate transformers inside the RepositoryQuery:

if(_distinctRootEntity)
{
query.QueryOptions.RegisterCustomAction(x => x.SetResultTransformer(Transformers.DistinctRootEntity));
}

Any thoughts?

StackOverflow

Method "public void RegisterGeneric(Type service, Type implementation)" calls its self, in StructureMapContainerAdapter.cs line 100.

    public void RegisterGeneric(Type service, Type implementation)
    {
        RegisterGeneric(service, implementation);
    }

shoud be

    public void RegisterGeneric(Type service, Type implementation)
    {
        Register(service, implementation);
    }

Attaching "nested" models

Hi,

I have a service layer from with I pull some data in a UoW scope. I do some eager fetching the retrieve associated data. Then i perform actions on this model object, change data, adding new entities to an association collection etc. My problem is when I send the changed object back for processing in my service layer. I had some proplem updating the object, getting an error saying something like that the object already exist in the ObjectStateManager. What I did is attaching the "root" object. However this did not result in an update/save of changed properties in the child object. I had to loop each child association and then attach them the their own reposiotory. Something like this:

using (var scope = new UnitOfWorkScope())
{
var rootDomainRepository = new EFRepository();
var childRepos = new EFRepository();
myrootobject.SomeMethod() //argument in service method
myrootobject.Children.ForEach( c => childRepos.Attach(c));
rootDomainRepository.Attach(myrootobject);
scope.Commit();
}

Now, is this the way to do it? Would it be possible to add support for attaching children/association when attaching a parent object? Or am I doing something fundementally wrong:)

IRepository<T>.Save

Im confused with IRepository.Save method.
Especially in EF implementation, this method is used to Add/Insert object to repository not to Update/Save changes made on it.

How did you mean it?

Specification usage error

Hi there

I found a strange thing happening when using specification
If you run this test ( you can add it to the NHRepositoryTests.cs in namespace NCommon.Data.NHibernate.Tests) :

    [Test]
    public void Query_Using_OrderBy_In_Specification()
    {
        using (var testData = new NHTestDataGenerator(Factory.OpenSession()))
        using (new UnitOfWorkScope())
        {
            testData.Batch(actions =>
            {
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("PA", 2));
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("DE", 5));
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("LA", 3));
            });

            var customersInPA = new Specification<Order>(x => string.Compare( x.Customer.Address.State , "PA")==0);
            var ordersRepository = new NHRepository<Order>();
            var results = from order in ordersRepository.Query(customersInPA)
                          orderby order.OrderDate
                          select order;

            Assert.That(results.Count() > 0);
            Assert.That(results.Count(), Is.EqualTo(2));
        }
    }

The test fails with a QueryException
NHibernate.QueryException: Cannot use subqueries on a criteria without a projection.
However, all works fine if you try this

    [Test]
    public void Query_Using_Specification()
    {
        using (var testData = new NHTestDataGenerator(Factory.OpenSession()))
        using (new UnitOfWorkScope())
        {
            testData.Batch(actions =>
            {
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("PA", 2));
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("DE", 5));
                actions.CreateOrdersForCustomers(actions.CreateCustomersInState("LA", 3));
            });

            var customersInPA = new Specification<Order>(x => string.Compare( x.Customer.Address.State , "PA", StringComparison.OrdinalIgnoreCase)==0);
            var ordersRepository = new NHRepository<Order>();

            Assert.DoesNotThrow(() => ordersRepository.Query(customersInPA).OrderBy(x=>x.OrderDate));

        }
    }

The key here seems to be doing things with a Query()

**Note: I just re ran the test and the passing test means nothing, as , as soon as you want to do anything with the collection it throws

Otherwise The library is great
I ll update if I find a solution to this
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.