autofac和拥有的实例

时间:2017-06-07 14:48:43

标签: c# autofac

我一直在讨论拥有的实例,我需要设置一个。 http://docs.autofac.org/en/latest/advanced/owned-instances.html

我在同一个类中有2个方法使用这个拥有的实例。我把它设置成这样:

private readonly Func<SessionDetails, Owned<ITroposUnitOfWork>> _paramatizedTroposUnitOfWork;

我的工作类构造函数如下所示:

/// <summary>
/// Used for creating manual sessions
/// </summary>
/// <param name="sessionDetails">The details of the session to be created</param>
public TroposUnitOfWork(SessionDetails sessionDetails)
{

    // Throw if we don't supply any details
    ThrowIf.ArgumentIsNull(() => sessionDetails);

    // Start the session
    StartSession(sessionDetails);
}

所以,我的理解是,如果我使用使用块,那么工作单元将在通话结束时被处理掉。但事实并非如此。 就像我之前提到的,我有2个方法使用这个拥有的实例。他们是:

/// <summary>
/// Creates the Tropos user
/// </summary>
/// <param name="model">The user to be created</param>
/// <param name="password">The password to set</param>
private async Task CreateTroposUserAsync(User model, string password)
{

    // If there is no password, throw an error
    ThrowIf.ArgumentIsNull(() => password);

    // Get our master user
    var user = await base.FindByNameAsync(model.Master);

    // If we have no master user, throw an error
    if (user == null) throw new ObjectNotFoundException();

    // Create our session details
    var sessionDetails = _troposSession.Value.Create(user);

    // User our new user
    using (var troposUnitOfWork = _paramatizedTroposUnitOfWork(sessionDetails))
    {

        try
        {

            // Create our tropos user service
            var userService = new TroposUserService(troposUnitOfWork.Value);

            // Create our user
            var transaction = userService.Create(model);

            // Save our changes (Don't throw an error if the user already exists)
            troposUnitOfWork.Value.RunTransaction(transaction);

        } catch (Exception ex)
        {

            // Display human readable messages
            throw new Exception(ex.Message);
        }
    }

    // Sets the new users password
    SetTroposPassword(model, password);

    // Update the flag
    model.HasTroposLogin = true;
}

另一个是:

/// <summary>
/// Sets the tropos password
/// </summary>
/// <param name="model">The user that needs the password setting</param>
/// <param name="password"></param>
private void SetTroposPassword(User model, string password)
{

    // Create our session details
    var sessionDetails = _troposSession.Value.Create(model.UserName);

    // Create our anonymous session
    using (var troposUnitOfWork = _paramatizedTroposUnitOfWork(sessionDetails))
    {

        // Create our tropos user service
        var userService = new TroposUserService(troposUnitOfWork.Value);

        // Set our password
        var transaction = userService.ChangePassword(password);

        // Save our changes
        troposUnitOfWork.Value.RunTransaction(transaction);
    }
}

第一种方法会调用第二种方法,但在使用块之外。我在 TroposUnitOfWork dispose方法中设置了一个断点,它只被击中一次。构造函数也只被命中一次。 有谁知道为什么?

1 个答案:

答案 0 :(得分:0)

我们需要看到_paramatizedTroposUnitOfWork的初始化。 CreateTroposUserAsync方法有哪些类?我们需要看到该类的构造函数。我想你的总体目标是实现一个工作单元。

您只打了一次构造函数的原因可能是由于您在注册时使用的生命周期。如果它拥有。然后,这两种方法可能在相同的生命周期范围内执行,并且依赖关系仅解析一次。或者换句话说_paramatizedTroposUnitOfWork(sessionDetails)返回相同的实例。

我使用装饰器和工厂解决了类似的问题

public interface IEventHandlerFactory<in TNotification> where TNotification 
    : class, IAsyncNotification
{
    IAsyncNotificationHandler<TNotification> Create( ILifetimeScope 
                                                           lifetimeScope );
}

public class EventHandlerFactory<TNotification, TEventHandler> : 
       IEventHandlerFactory<TNotification>
       where TNotification : class, IAsyncNotification
       where TEventHandler : class, IAsyncNotificationHandler<TNotification>
{
    public IAsyncNotificationHandler<TNotification> Create( ILifetimeScope 
                   lifetimeScope )
    {
        return lifetimeScope.ResolveNamed<TEventHandler>( "EventHandler" ) 
                      as IAsyncNotificationHandler<TNotification>;
    }
}

完整.net小提琴在这里https://dotnetfiddle.net/fw4IBw